Script 8 for Kitchel et al.Ā 2024 in prep taxonomic diversity manuscript.

library(data.table)
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     
data.table 1.14.8 using 1 threads (see ?getDTthreads).  Latest news: r-datatable.com
**********
This installation of data.table has not detected OpenMP support. It should still work but in single-threaded mode.
This is a Mac. Please read https://mac.r-project.org/openmp/. Please engage with Apple and ask them for support. Check r-datatable.com for updates, and our Mac instructions here: https://github.com/Rdatatable/data.table/wiki/Installation. After several years of many reports of installation problems on Mac, it's time to gingerly point out that there have been no similar problems on Windows or Linux.
**********
library(MuMIn)
library(ggplot2)
library(cowplot)
library(lme4)
Loading required package: Matrix
library(stringr)
library(nlme)

Attaching package: ā€˜nlme’

The following object is masked from ā€˜package:lme4’:

    lmList
#pull in function to calculate model estimates and standard errors
source(here::here("analysis_code","extract_coefficients_function.R"))

###Predicts annual dissimilarity with annual characteristics, temperature and fishing values

Pull in - region areas (if not already loaded) - region characteristics (if not already loaded); saveRDS(FishGlob_richness_year_survey, file = here::here(ā€œoutputā€,ā€œFishGlob_richness_year_survey.Rdsā€)) - fishing (if not already loaded) - temp (if not already loaded)

#physical area by year
region_area_byyear <- fread(here::here("output","region_area_byyear.csv"))

#merged fishing, temp, dissimilarities
dissimilarities_temp_fishing <- fread(here::here("output","dissimilarities_temp_fishing.csv"))

#combine
dissimilarities_temp_fishing_area <- dissimilarities_temp_fishing[region_area_byyear, on = c("survey_unit","year")]

#only jaccard for these analyses
dissimilarities_temp_fishing_area.jaccard <- dissimilarities_temp_fishing_area[dissimilarity_metric == "jaccard_dissimilarity_index_binary",]

Add in season

#load up julian days
dates_regions <- readRDS(here::here("output","dates_regions.rds"))

#most common season per year
# Function to get the most frequent value
get_mode <- function(x) {
  ux <- unique(x)
  ux[which.max(tabulate(match(x, ux)))]
}

# Apply the function to each group
dates_regions.r <- dates_regions[, .(season = get_mode(season)), by = c("survey_unit","year")]


#merge
dissimilarities_temp_fishing_area.jaccard <- dates_regions.r[dissimilarities_temp_fishing_area.jaccard, on = c("survey_unit","year")]

Pull in palette and name helper

source(here::here("analysis_code","color_links.R"))

Pull in observed trend values

jaccard_total_coefs.r <- fread(here::here("output","jaccard_total_coefs.r.csv"))

Plot fishing and temperature vs.Ā time for all regions

#######TEMPERATURE

#set order by survey unit for plotting
all_surveys <- levels(as.factor(dissimilarities_temp_fishing_area.jaccard$survey_unit))
setorder(dissimilarities_temp_fishing_area.jaccard, survey_unit)

dissimilarities_temp_fishing_area.jaccard[,Survey_Name_Season:=factor(Survey_Name_Season, levels = unique(dissimilarities_temp_fishing_area.jaccard$Survey_Name_Season), ordered = T)]

(sbt_time_survey_facet_1_20 <- ggplot(data = dissimilarities_temp_fishing_area.jaccard[survey_unit %in% all_surveys[1:20] & year > 1979]) +
  labs(y = "Mean bottom temperature (˚C)",  x = "Year") +
  geom_point(aes(y = as.numeric(yearly_mean_bypoint_avg), x = year), alpha = 0.3) +
  geom_smooth(aes(y = as.numeric(yearly_mean_bypoint_avg), x = year), method = "lm") +
  scale_x_continuous(breaks = ~ axisTicks(., log = FALSE)) +
  theme_classic() +
  theme(axis.text.x = element_text(size = 7)) +
  facet_wrap(~Survey_Name_Season, scales= "free", ncol = 4))

ggsave(sbt_time_survey_facet_1_20, path = here::here("figures"), filename = "sbt_time_survey_facet_1_20.jpg", height = 12, width =9)


(sbt_time_survey_facet_21_34 <- ggplot(data = dissimilarities_temp_fishing_area.jaccard[survey_unit %in% all_surveys[21:34] & year > 1979]) +
  labs(y = "Mean bottom temperature (˚C)",  x = "Year") +
  geom_point(aes(y = as.numeric(yearly_mean_bypoint_avg), x = year), alpha = 0.3) +
  geom_smooth(aes(y = as.numeric(yearly_mean_bypoint_avg), x = year), method = "lm") +
  scale_x_continuous(breaks = ~ axisTicks(., log = FALSE)) +
  theme_classic() +
  theme(axis.text.x = element_text(size = 7)) +
  facet_wrap(~Survey_Name_Season, scales= "free", ncol = 4))

ggsave(sbt_time_survey_facet_21_34, path = here::here("figures"), filename = "sbt_time_survey_facet_21_34.jpg", height = 12, width =9)


#######FISHING

dissimilarities_temp_fishing_area.jaccard.cc <- dissimilarities_temp_fishing_area.jaccard[complete.cases(dissimilarities_temp_fishing_area.jaccard[,summed_tonnes_scaled_byreg]),]

(fishing_time_survey_facet_1_20 <- ggplot(data = dissimilarities_temp_fishing_area.jaccard.cc[survey_unit %in% all_surveys[1:20] & year > 1979]) +
  labs(y = "Relative fishing catch",  x = "Year") +
  geom_point(aes(y = summed_tonnes_scaled_byreg, x = year), alpha = 0.3) +
  geom_smooth(aes(y = summed_tonnes_scaled_byreg, x = year), method = "lm") +
  scale_x_continuous(breaks = ~ axisTicks(., log = FALSE)) +
  theme_classic() +
  theme(axis.text.x = element_text(size = 7)) +
  facet_wrap(~Survey_Name_Season, scales= "free", ncol = 4))

ggsave(fishing_time_survey_facet_1_20, path = here::here("figures"), filename = "fishing_time_survey_facet_1_20.jpg", height = 12, width =9)


(fishing_time_survey_facet_21_34 <- ggplot(data = dissimilarities_temp_fishing_area.jaccard.cc[survey_unit %in% all_surveys[c(21:34)] & year > 1979]) +
  labs(y = "Relative fishing catch",  x = "Year") +
  geom_point(aes(y = summed_tonnes_scaled_byreg, x = year), alpha = 0.3) +
  geom_smooth(aes(y = summed_tonnes_scaled_byreg, x = year), method = "lm") +
  scale_x_continuous(breaks = ~ axisTicks(., log = FALSE)) +
  theme_classic() +
  theme(axis.text.x = element_text(size = 7)) +
  facet_wrap(~Survey_Name_Season, scales= "free", ncol = 4))

ggsave(fishing_time_survey_facet_21_34, path = here::here("figures"), filename = "fishing_time_survey_facet_21_34.jpg", height = 12, width =9)

NA
NA

Plot fishing and temperature vs.Ā dissimilarity for all regions

#####MEAN TEMP
(preds_sbt_mean_temp_survey_facet_1_20 <- ggplot(data = dissimilarities_temp_fishing_area.jaccard[survey_unit %in% all_surveys[1:20] & year > 1979]) +
  labs(x = "Mean bottom temperature (˚C)",  y = "β-diversity") +
  geom_point(aes(x = as.numeric(yearly_mean_bypoint_avg), y = annual_dissimilarity_value), alpha = 0.3) +
  geom_smooth(aes(x = as.numeric(yearly_mean_bypoint_avg), y = annual_dissimilarity_value), method = "lm") +
  facet_wrap(~Survey_Name_Season, scales= "free", ncol = 4) +
  theme_classic())

ggsave(preds_sbt_mean_temp_survey_facet_1_20, path = here::here("figures"), filename = "preds_sbt_mean_temp_survey_facet_1_20.jpg", height = 12, width =9)


(preds_sbt_mean_temp_survey_facet_21_34 <- ggplot(data = dissimilarities_temp_fishing_area.jaccard[survey_unit %in% all_surveys[21:34] & year > 1979]) +
  labs(x = "Mean bottom temperature (˚C)",  y = "β-diversity") +
  geom_point(aes(x = as.numeric(yearly_mean_bypoint_avg), y = annual_dissimilarity_value), alpha = 0.3) +
  geom_smooth(aes(x = as.numeric(yearly_mean_bypoint_avg), y = annual_dissimilarity_value), method = "lm") +
  facet_wrap(~Survey_Name_Season, scales= "free", ncol = 4) +
  theme_classic())

ggsave(preds_sbt_mean_temp_survey_facet_21_34, path = here::here("figures"), filename = "preds_sbt_mean_temp_survey_facet_21_34.jpg", height = 12, width =9)


#####MINIMUM TEMP
(preds_sbt_min_temp_survey_facet_1_20 <- ggplot(data = dissimilarities_temp_fishing_area.jaccard[survey_unit %in% all_surveys[1:20] & year > 1979]) +
  labs(x = "Minimum bottom temperature (˚C)",  y = "β-diversity") +
  geom_point(aes(x = as.numeric(yearly_min_bypoint_avg), y = annual_dissimilarity_value), alpha = 0.3) +
  geom_smooth(aes(x = as.numeric(yearly_min_bypoint_avg), y = annual_dissimilarity_value), method = "lm") +
  facet_wrap(~Survey_Name_Season, scales= "free", ncol = 4) +
  theme_classic())

ggsave(preds_sbt_min_temp_survey_facet_1_20, path = here::here("figures"), filename = "preds_sbt_min_temp_survey_facet_1_20.jpg", height = 12, width =9)


(preds_sbt_min_temp_survey_facet_21_34 <- ggplot(data = dissimilarities_temp_fishing_area.jaccard[survey_unit %in% all_surveys[21:34] & year > 1979]) +
  labs(x = "Minimum bottom temperature (˚C)",  y = "β-diversity") +
  geom_point(aes(x = as.numeric(yearly_min_bypoint_avg), y = annual_dissimilarity_value), alpha = 0.3) +
  geom_smooth(aes(x = as.numeric(yearly_min_bypoint_avg), y = annual_dissimilarity_value), method = "lm") +
  facet_wrap(~Survey_Name_Season, scales= "free", ncol = 4) +
  theme_classic())

ggsave(preds_sbt_min_temp_survey_facet_21_34, path = here::here("figures"), filename = "preds_sbt_min_temp_survey_facet_21_34.jpg", height = 12, width =9)


#######FISHING

dissimilarities_temp_fishing_area.jaccard.cc <- dissimilarities_temp_fishing_area.jaccard[complete.cases(dissimilarities_temp_fishing_area.jaccard[,summed_tonnes_scaled_byreg]),]

(preds_sbt_mean_fishing_survey_facet_1_20 <- ggplot(data = dissimilarities_temp_fishing_area.jaccard.cc[survey_unit %in% all_surveys[1:20] & year > 1979]) +
  labs(x = "Relative fishing catch",  y = "β-diversity") +
  geom_point(aes(x = summed_tonnes_scaled_byreg, y = annual_dissimilarity_value), alpha = 0.3) +
  geom_smooth(aes(x = summed_tonnes_scaled_byreg, y = annual_dissimilarity_value), method = "lm") +
  facet_wrap(~Survey_Name_Season, scales= "free", ncol = 4) +
  theme_classic())

ggsave(preds_sbt_mean_fishing_survey_facet_1_20, path = here::here("figures"), filename = "preds_sbt_mean_fishing_survey_facet_1_20.jpg", height = 12, width =9)


(preds_sbt_mean_fishing_survey_facet_21_34 <- ggplot(data = dissimilarities_temp_fishing_area.jaccard.cc[survey_unit %in% all_surveys[c(21:34)] & year > 1979]) +
  labs(x = "Relative fishing catch",  y = "β-diversity") +
  geom_point(aes(x = summed_tonnes_scaled_byreg, y = annual_dissimilarity_value), alpha = 0.3) +
  geom_smooth(aes(x = summed_tonnes_scaled_byreg, y = annual_dissimilarity_value), method = "lm") +
  facet_wrap(~Survey_Name_Season, scales= "free", ncol = 4) +
  theme_classic())

ggsave(preds_sbt_mean_fishing_survey_facet_21_34, path = here::here("figures"), filename = "preds_sbt_mean_fishing_survey_facet_21_34.jpg", height = 12, width =9)

NA
NA

###Plot number of tows per year per region

tows_year <- unique(dissimilarities_temp_fishing_area.jaccard[,.(survey_unit, haul_id_count_annual, area_km, year, Survey_Name_Season)])

min_haul_density <- min(tows_year$haul_id_count_annual/tows_year$area_km)
max_haul_density <- max(tows_year$haul_id_count_annual/tows_year$area_km)

(tow_density_survey_facet_1_20 <- ggplot(data = tows_year[survey_unit %in% all_surveys[1:20]]) +
  labs(x = "Year",  y = expression("Tow density (tows per km"^2*")")) +
  geom_point(aes(x = year, y = haul_id_count_annual/area_km)) +
  ylim(c(min_haul_density-0.0001, max_haul_density+0.0001)) +
  facet_wrap(~Survey_Name_Season, ncol = 4) +
  theme_classic())

ggsave(tow_density_survey_facet_1_20, path = here::here("figures"), filename = "tow_density_survey_facet_1_20.jpg", height = 12, width =9)


(tow_density_survey_facet_21_34 <- ggplot(data = tows_year[survey_unit %in% all_surveys[21:34]]) +
  labs(x = "Year",  y = expression("Tow density (tows per km"^2*")")) +
  geom_point(aes(x = year, y = haul_id_count_annual/area_km)) +
  ylim(c(min_haul_density-0.0001, max_haul_density+0.0001)) +
  facet_wrap(~Survey_Name_Season, ncol = 4) +
  theme_classic())

ggsave(tow_density_survey_facet_21_34, path = here::here("figures"), filename = "tow_density_survey_facet_21_34.jpg", height = 12, width =9)

#minimum and maximum dissimilarity value
min_dissimilarity <- min(dissimilarities_temp_fishing_area.jaccard$annual_dissimilarity_value)
max_dissimilarity <- max(dissimilarities_temp_fishing_area.jaccard$annual_dissimilarity_value)

#how does tow density vary with dissimilarity?
tow_density_dissimilarity_1_20 <- 
  ggplot(data = dissimilarities_temp_fishing_area.jaccard[dissimilarity_metric == "jaccard_dissimilarity_index_binary" & survey_unit %in% all_surveys[1:20]]) +
  geom_point(aes(x = (haul_id_count_annual/area_km), y = annual_dissimilarity_value, color = year), size = 2) +
  viridis::scale_color_viridis() +
  facet_wrap(~Survey_Name_Season, ncol = 4, scales = "free") +
  labs(x = expression("Tow density (tows per km"^2*")"), y = "β-diversity", color = "Year") +
   # xlim(c(min_haul_density-0.0001, max_haul_density+0.0001)) +
   # ylim(c(min_dissimilarity-0.01,max_dissimilarity+0.01)) +
  theme_classic() +
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1))

ggsave(tow_density_dissimilarity_1_20, path = here::here("figures"), filename = "tow_density_dissimilarity_1_20.jpg", height = 12, width =9)

tow_density_dissimilarity_21_34 <- 
  ggplot(data = dissimilarities_temp_fishing_area.jaccard[dissimilarity_metric == "jaccard_dissimilarity_index_binary" & survey_unit %in% all_surveys[21:34]]) +
  geom_point(aes(x = (haul_id_count_annual/area_km), y = annual_dissimilarity_value, color = year), size = 2) +
  viridis::scale_color_viridis() +
  facet_wrap(~Survey_Name_Season, ncol = 4, scales = "free") +
  labs(x = expression("Tow density (tows per km"^2*")"), y = "β-diversity", color = "Year") +
   # xlim(c(min_haul_density-0.0001, max_haul_density+0.0001)) +
   # ylim(c(min_dissimilarity-0.01,max_dissimilarity+0.01)) +
  theme_classic() +
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust = 1))

ggsave(tow_density_dissimilarity_21_34, path = here::here("figures"), filename = "tow_density_dissimilarity_21_34.jpg", height = 12, width =9)



#Plot all at once?
tow_density_dissimilarity <- 
  ggplot(data = dissimilarities_temp_fishing_area.jaccard[dissimilarity_metric == "jaccard_dissimilarity_index_binary"]) +
  geom_point(aes(x = (haul_id_count_annual/area_km), y = annual_dissimilarity_value, color = Survey_Name_Season), size = 2) +
  scale_color_manual(values = color_link$hex) +
  labs(x = expression("Tow density (tows per km"^2*")"), y = "β-diversity", color = "Year") +
   # xlim(c(min_haul_density-0.0001, max_haul_density+0.0001)) +
   # ylim(c(min_dissimilarity-0.01,max_dissimilarity+0.01)) +
  theme_classic()

#and by numbers?
result <- dissimilarities_temp_fishing_area.jaccard[, .(max_density = max(haul_id_count_annual/area_km, na.rm = TRUE), 
                 min_density = min(haul_id_count_annual/area_km, na.rm = TRUE)), 
             by = Survey_Name_Season]

result[,range:= max_density-min_density]

ggplot(data = result) +
  geom_point(aes(x = Survey_Name_Season, y = range)) +
  theme_classic() +
  labs(x = "",y = "Range of tow density values in tow/km^2") +
  theme(axis.text.x = element_text(angle = 45, hjust=1))

Dissimilarity by season of sampling

dissimilarities_temp_fishing_area.jaccard[,season := factor(season, levels = c("Spring","Summer","Fall","Winter"))]

ggplot(dissimilarities_temp_fishing_area.jaccard) +
  geom_boxplot(aes(x = season, y = annual_dissimilarity_value)) +
  theme_classic()

###Set up dredge to identify best performing models


options(na.action = "na.fail")

dissimilarity_covariates_dredge.dt <- dissimilarities_temp_fishing_area.jaccard[,.
                  (year, survey_unit,
                    yearly_mean_bypoint_avg, yearly_max_bypoint_avg, yearly_min_bypoint_avg,yearly_seas_bypoint_avg,
                    yearly_mean_bypoint_SD, yearly_max_bypoint_SD, yearly_min_bypoint_SD,yearly_seas_bypoint_SD,
                    yearly_mean_bypoint_avg.s, yearly_max_bypoint_avg.s, yearly_min_bypoint_avg.s,yearly_seas_bypoint_avg.s,
                    annual_dissimilarity_value,
                    haul_id_count_annual,
                    spp_count_annual, depth_annual_avg,
                    depth_annual_range, latitude_annual_avg,
                    latitude_annual_range, area_km, season, summed_tonnes_scaled_byreg)]

#merge in with colors for plotting predictions by survey
dissimilarity_covariates_dredge.dt <- color_link[dissimilarity_covariates_dredge.dt, on = "survey_unit"]

#If NA for any covariate, delete row
#View(dissimilarity_covariates_dredge.dt)
#Deleted:
  #Before 1980 and after 2019
  #Gulf of Saint Laurence South (no depth data)
  #No clear SAU match for Rockall Plateau
dissimilarity_covariates_dredge.dt <- dissimilarity_covariates_dredge.dt[complete.cases(dissimilarity_covariates_dredge.dt)]


dissimilarity_covariates_dredge.dt[, yearly_mean_bypoint_avg.scaledacrossall := scale(yearly_mean_bypoint_avg)][, yearly_mean_bypoint_SD.scaledacrossall := scale(yearly_mean_bypoint_SD)][, yearly_min_bypoint_avg.scaledacrossall := scale(yearly_min_bypoint_avg)][, yearly_max_bypoint_avg.scaledacrossall := scale(yearly_max_bypoint_avg)][, yearly_seas_bypoint_avg.scaledacrossall := scale(yearly_seas_bypoint_avg)][,haul_id_count_annual.scaledacrossall := scale(haul_id_count_annual)][,spp_count_annual.scaledacrossall := scale(spp_count_annual)][,depth_annual_avg.scaledacrossall := scale(depth_annual_avg)][,depth_annual_range.scaledacrossall := scale(depth_annual_range)] [,latitude_annual_avg.scaledacrossall := scale(latitude_annual_avg)][,latitude_annual_range.scaledacrossall := scale(latitude_annual_range)][,area_km.scaledacrossall := scale(area_km)]
###Full model
temp + survey_unit + fishing + area + latitude range + latitude average + depth range + depth average + spp count + # of hauls + season + AR for year

For temperature, we will look at: -mean (scaled across all regions) -max (scaled across all regions) -min (scaled across all regions) -seas (scaled across all regions) -SD

Comparing temp variables AND the presence/absence random effect for year


global_mod_mean_temp_lmer_surveyyear <- lmer(annual_dissimilarity_value ~ 
                             survey_unit:yearly_mean_bypoint_avg.scaledacrossall + #temp and survey unit (possible interaction)
                             survey_unit:summed_tonnes_scaled_byreg + #fishing effort and survey unit (possible interaction)
                             area_km.scaledacrossall + #area
                             latitude_annual_range.scaledacrossall + #latitude range
                             latitude_annual_avg.scaledacrossall + #latitude avg
                             depth_annual_range.scaledacrossall + #depth range
                             depth_annual_avg.scaledacrossall + #depth avg
                             spp_count_annual.scaledacrossall + #spp #
                             haul_id_count_annual.scaledacrossall +
                             season + yearly_mean_bypoint_avg.scaledacrossall + summed_tonnes_scaled_byreg +
                               (1|survey_unit) + (1|year),
                             data = dissimilarity_covariates_dredge.dt)

global_mod_mean_temp_lmer_survey <- lmer(annual_dissimilarity_value ~ 
                             survey_unit:yearly_mean_bypoint_avg.scaledacrossall + #temp and survey unit (possible interaction)
                             survey_unit:summed_tonnes_scaled_byreg + #fishing effort and survey unit (possible interaction)
                             area_km.scaledacrossall + #area
                             latitude_annual_range.scaledacrossall + #latitude range
                             latitude_annual_avg.scaledacrossall + #latitude avg
                             depth_annual_range.scaledacrossall + #depth range
                             depth_annual_avg.scaledacrossall + #depth avg
                             spp_count_annual.scaledacrossall + #spp #
                             haul_id_count_annual.scaledacrossall +
                             season + yearly_mean_bypoint_avg.scaledacrossall + summed_tonnes_scaled_byreg +
                               (1|survey_unit),
                             data = dissimilarity_covariates_dredge.dt)

global_mod_max_temp_lmer_surveyyear <- lmer(annual_dissimilarity_value ~ 
                             survey_unit:yearly_max_bypoint_avg.scaledacrossall + #temp and survey unit (possible interaction)
                             survey_unit:summed_tonnes_scaled_byreg + #fishing effort and survey unit (possible interaction)
                             area_km.scaledacrossall + #area
                             latitude_annual_range.scaledacrossall + #latitude range
                             latitude_annual_avg.scaledacrossall + #latitude avg
                             depth_annual_range.scaledacrossall + #depth range
                             depth_annual_avg.scaledacrossall + #depth avg
                             spp_count_annual.scaledacrossall + #spp #
                             haul_id_count_annual.scaledacrossall +
                             season + yearly_mean_bypoint_avg.scaledacrossall + summed_tonnes_scaled_byreg +
                               (1|survey_unit) + (1|year),
                             data = dissimilarity_covariates_dredge.dt)

global_mod_max_temp_lmer_survey <- lmer(annual_dissimilarity_value ~ 
                             survey_unit:yearly_max_bypoint_avg.scaledacrossall + #temp and survey unit (possible interaction)
                             survey_unit:summed_tonnes_scaled_byreg + #fishing effort and survey unit (possible interaction)
                             area_km.scaledacrossall + #area
                             latitude_annual_range.scaledacrossall + #latitude range
                             latitude_annual_avg.scaledacrossall + #latitude avg
                             depth_annual_range.scaledacrossall + #depth range
                             depth_annual_avg.scaledacrossall + #depth avg
                             spp_count_annual.scaledacrossall + #spp #
                             haul_id_count_annual.scaledacrossall +
                             season + yearly_mean_bypoint_avg.scaledacrossall + summed_tonnes_scaled_byreg +
                               (1|survey_unit),
                             data = dissimilarity_covariates_dredge.dt)

global_mod_min_temp_lmer_surveyyear <- lmer(annual_dissimilarity_value ~ 
                             survey_unit:yearly_min_bypoint_avg.scaledacrossall + #temp and survey unit (possible interaction)
                             survey_unit:summed_tonnes_scaled_byreg + #fishing effort and survey unit (possible interaction)
                             area_km.scaledacrossall + #area
                             latitude_annual_range.scaledacrossall + #latitude range
                             latitude_annual_avg.scaledacrossall + #latitude avg
                             depth_annual_range.scaledacrossall + #depth range
                             depth_annual_avg.scaledacrossall + #depth avg
                             spp_count_annual.scaledacrossall + #spp #
                             haul_id_count_annual.scaledacrossall +
                             season + yearly_mean_bypoint_avg.scaledacrossall + summed_tonnes_scaled_byreg +
                               (1|survey_unit) + (1|year),
                             data = dissimilarity_covariates_dredge.dt)

dissimilarity_covariates_dredge.dt[, survey_unit := factor(survey_unit, levels = sort(all_surveys))]

global_mod_min_temp_lmer_survey <-lmer(annual_dissimilarity_value ~ 
                             survey_unit:yearly_min_bypoint_avg.scaledacrossall + #temp and survey unit (possible interaction)
                             survey_unit:summed_tonnes_scaled_byreg + #fishing effort and survey unit (possible interaction)
                             area_km.scaledacrossall + #area
                             latitude_annual_range.scaledacrossall + #latitude range
                             latitude_annual_avg.scaledacrossall + #latitude avg
                             depth_annual_range.scaledacrossall + #depth range
                             depth_annual_avg.scaledacrossall + #depth avg
                             spp_count_annual.scaledacrossall + #spp #
                             haul_id_count_annual.scaledacrossall +
                             season + yearly_mean_bypoint_avg.scaledacrossall + summed_tonnes_scaled_byreg +
                               (1|survey_unit),
                             data = dissimilarity_covariates_dredge.dt)

global_mod_seas_temp_lmer_surveyyear <- lmer(annual_dissimilarity_value ~ 
                             survey_unit:yearly_seas_bypoint_avg.scaledacrossall + #temp and survey unit (possible interaction)
                             survey_unit:summed_tonnes_scaled_byreg + #fishing effort and survey unit (possible interaction)
                             area_km.scaledacrossall + #area
                             latitude_annual_range.scaledacrossall + #latitude range
                             latitude_annual_avg.scaledacrossall + #latitude avg
                             depth_annual_range.scaledacrossall + #depth range
                             depth_annual_avg.scaledacrossall + #depth avg
                             spp_count_annual.scaledacrossall + #spp #
                             haul_id_count_annual.scaledacrossall +
                             season + yearly_mean_bypoint_avg.scaledacrossall + summed_tonnes_scaled_byreg +
                               (1|survey_unit) + (1|year),
                             data = dissimilarity_covariates_dredge.dt)

global_mod_seas_temp_lmer_survey <- lmer(annual_dissimilarity_value ~ 
                             survey_unit:yearly_seas_bypoint_avg.scaledacrossall + #temp and survey unit (possible interaction)
                             survey_unit:summed_tonnes_scaled_byreg + #fishing effort and survey unit (possible interaction)
                             area_km.scaledacrossall + #area
                             latitude_annual_range.scaledacrossall + #latitude range
                             latitude_annual_avg.scaledacrossall + #latitude avg
                             depth_annual_range.scaledacrossall + #depth range
                             depth_annual_avg.scaledacrossall + #depth avg
                             spp_count_annual.scaledacrossall + #spp #
                             haul_id_count_annual.scaledacrossall +
                             season + yearly_mean_bypoint_avg.scaledacrossall + summed_tonnes_scaled_byreg +
                               (1|survey_unit),
                             data = dissimilarity_covariates_dredge.dt)

global_mod_SD_temp_lmer_surveyyear <- lmer(annual_dissimilarity_value ~ 
                             survey_unit:yearly_mean_bypoint_SD.scaledacrossall + #temp and survey unit (possible interaction)
                             survey_unit:summed_tonnes_scaled_byreg + #fishing effort and survey unit (possible interaction)
                             area_km.scaledacrossall + #area
                             latitude_annual_range.scaledacrossall + #latitude range
                             latitude_annual_avg.scaledacrossall + #latitude avg
                             depth_annual_range.scaledacrossall + #depth range
                             depth_annual_avg.scaledacrossall + #depth avg
                             spp_count_annual.scaledacrossall + #spp #
                             haul_id_count_annual.scaledacrossall +
                             season + yearly_mean_bypoint_avg.scaledacrossall + summed_tonnes_scaled_byreg +
                               (1|survey_unit) + (1|year),
                             data = dissimilarity_covariates_dredge.dt)

global_mod_SD_temp_lmer_survey <- lmer(annual_dissimilarity_value ~ 
                             survey_unit:yearly_mean_bypoint_SD.scaledacrossall + #temp and survey unit (possible interaction)
                             survey_unit:summed_tonnes_scaled_byreg + #fishing effort and survey unit (possible interaction)
                             area_km.scaledacrossall + #area
                             latitude_annual_range.scaledacrossall + #latitude range
                             latitude_annual_avg.scaledacrossall + #latitude avg
                             depth_annual_range.scaledacrossall + #depth range
                             depth_annual_avg.scaledacrossall + #depth avg
                             spp_count_annual.scaledacrossall + #spp #
                             haul_id_count_annual.scaledacrossall +
                             season + yearly_mean_bypoint_avg.scaledacrossall + summed_tonnes_scaled_byreg +
                               (1|survey_unit),
                             data = dissimilarity_covariates_dredge.dt)

View(AICc(global_mod_mean_temp_lmer_survey, global_mod_max_temp_lmer_survey, global_mod_min_temp_lmer_survey, global_mod_seas_temp_lmer_survey, global_mod_SD_temp_lmer_survey,
          global_mod_mean_temp_lmer_surveyyear, global_mod_max_temp_lmer_surveyyear, global_mod_min_temp_lmer_surveyyear, global_mod_seas_temp_lmer_surveyyear, global_mod_SD_temp_lmer_surveyyear))

#build data table to report AICc
global_mod_temp_table <- data.table(
  `Random effect year` = c(
    c(rep(F,5),rep(T,5))
  ),
  `Temperature variable` = rep(c(                  
              "Average mean SBT",
              "Average maximum SBT",                        
              "Average minimum SBT",                  
              "Average SBT seasonality",                 
              "SBT SD"),2),
  deltaAICc = signif(min(AICc(global_mod_mean_temp_lmer_survey, global_mod_max_temp_lmer_survey, global_mod_min_temp_lmer_survey, global_mod_seas_temp_lmer_survey, global_mod_SD_temp_lmer_survey,
          global_mod_mean_temp_lmer_surveyyear, global_mod_max_temp_lmer_surveyyear, global_mod_min_temp_lmer_surveyyear, global_mod_seas_temp_lmer_surveyyear, global_mod_SD_temp_lmer_surveyyear)[,2])-AICc(global_mod_mean_temp_lmer_survey, global_mod_max_temp_lmer_survey, global_mod_min_temp_lmer_survey, global_mod_seas_temp_lmer_survey, global_mod_SD_temp_lmer_survey,
          global_mod_mean_temp_lmer_surveyyear, global_mod_max_temp_lmer_surveyyear, global_mod_min_temp_lmer_surveyyear, global_mod_seas_temp_lmer_surveyyear, global_mod_SD_temp_lmer_surveyyear)[,2],2))

#order by aicc
setorder(global_mod_temp_table,cols = -"deltaAICc")

global_mod_temp_table[,Rank := seq(1,10,by = 1)]

global_mod_sbt_table <- global_mod_temp_table[,.(Rank,`Random effect year`,`Temperature variable`, deltaAICc)]

fwrite(global_mod_sbt_table, here::here("output","global_mod_sbt_table.csv"))

Best performing global model includes minimum temperature (centered and scaled) (Still the case as of October 4, 2024)

Now, look at different combinations of all predictors (min temp) using dredge

Global model: global_mod_min_temp

colnames(dd.dt.2)
 [1] "(Intercept)"                                         "area_km.scaledacrossall"                            
 [3] "depth_annual_avg.scaledacrossall"                    "depth_annual_range.scaledacrossall"                 
 [5] "haul_id_count_annual.scaledacrossall"                "latitude_annual_avg.scaledacrossall"                
 [7] "latitude_annual_range.scaledacrossall"               "season"                                             
 [9] "spp_count_annual.scaledacrossall"                    "summed_tonnes_scaled_byreg"                         
[11] "yearly_mean_bypoint_avg.scaledacrossall"             "summed_tonnes_scaled_byreg:survey_unit"             
[13] "survey_unit:yearly_mean_bypoint_avg.scaledacrossall" "df"                                                 
[15] "logLik"                                              "AICc"                                               
[17] "delta"                                               "weight"                                             

Predict dissimilarity across years using averaged model (model_avg_delta4)

dissimilarity_covariates_dredge.dt_predictions <- copy(dissimilarity_covariates_dredge.dt)

  #allowing temp and fishing to vary (aka no changes)
  dissimilarity_covariates_dredge.dt_predictions[,pred_dissim := predict(model_avg_delta4, se.fit = T, full = F)[[1]]][,pred_se := predict(model_avg_delta4, se.fit = T, full = F)[[2]]] #full allows us to switch back to mixed effect models
Warning: argument 'full' ignoredWarning: argument 'full' ignored
  
  
  
  #constant temp in regions (aka take mean of temperature values within survey units so they are the same value within each year for a survey)
  dissimilarity_covariates_dredge.dt_predictions_consistenttempinreg <- copy(dissimilarity_covariates_dredge.dt)
  dissimilarity_covariates_dredge.dt_predictions_consistenttempinreg[,yearly_min_bypoint_avg.scaledacrossall:=mean(yearly_min_bypoint_avg.scaledacrossall),.(survey_unit)]

  #constant fishing in regions (aka take mean of fishing values within survey units so they are the same value within each year for a survey)
  dissimilarity_covariates_dredge.dt_predictions_consistentfishinginreg <- copy(dissimilarity_covariates_dredge.dt)
  dissimilarity_covariates_dredge.dt_predictions_consistentfishinginreg[,summed_tonnes_scaled_byreg:=mean(summed_tonnes_scaled_byreg),.(survey_unit)]

#and then with consistent temp and fishing in regions (aka take mean of both min temp and fishing)
dissimilarity_covariates_dredge.dt_predictions_consistenttempfishinginreg <- copy(dissimilarity_covariates_dredge.dt)
dissimilarity_covariates_dredge.dt_predictions_consistenttempfishinginreg[,summed_tonnes_scaled_byreg:=mean(summed_tonnes_scaled_byreg),.(survey_unit)][,yearly_min_bypoint_avg.scaledacrossall:=mean(yearly_min_bypoint_avg.scaledacrossall),.(survey_unit)]


#allowing temp and fishing to vary within regs (normal)
    dissimilarity_covariates_dredge.dt_predictions[,pred_dissim := 
                                                     predict(model_avg_delta4, se.fit = T, full = F, newdata =   dissimilarity_covariates_dredge.dt_predictions)[[1]]][,pred_se := 
                                                                                                                                                                         predict(model_avg_delta4, se.fit = T, full = F, newdata =   dissimilarity_covariates_dredge.dt_predictions)[[2]]]
Warning: argument 'full' ignoredWarning: argument 'full' ignored
  
#allowing only fishing to vary within regions (with mean temp)
  
   dissimilarity_covariates_dredge.dt_predictions_consistenttempinreg[,pred_dissim := 
                                                                        predict(model_avg_delta4, se.fit = T, full = F, newdata = dissimilarity_covariates_dredge.dt_predictions_consistenttempinreg)[[1]]][,pred_se :=
                                                                                                                                                                                                              predict(model_avg_delta4, se.fit = T, full = F, newdata = dissimilarity_covariates_dredge.dt_predictions_consistenttempinreg)[[2]]]
Warning: argument 'full' ignoredWarning: argument 'full' ignored
  
  
#allowing only temperature to vary within regions (with mean fishing pressure)
     
   dissimilarity_covariates_dredge.dt_predictions_consistentfishinginreg[,pred_dissim :=
                                                                           predict(model_avg_delta4, se.fit = T, full = F, newdata = dissimilarity_covariates_dredge.dt_predictions_consistentfishinginreg)[[1]]][,pred_se := 
                                                                                                                                                                                                                                  predict(model_avg_delta4, se.fit = T, full = F, newdata = dissimilarity_covariates_dredge.dt_predictions_consistentfishinginreg)[[2]]]
Warning: argument 'full' ignoredWarning: argument 'full' ignored
   
#and then with consistent temp and fishing across regions (mean of both fishing and temp)
dissimilarity_covariates_dredge.dt_predictions_consistenttempfishinginreg <- copy(dissimilarity_covariates_dredge.dt)
dissimilarity_covariates_dredge.dt_predictions_consistenttempfishinginreg[,summed_tonnes_scaled_byreg:=mean(summed_tonnes_scaled_byreg),.(survey_unit)][,yearly_min_bypoint_avg.scaledacrossall:=mean(yearly_min_bypoint_avg.scaledacrossall),.(survey_unit)]

dissimilarity_covariates_dredge.dt_predictions_consistenttempfishinginreg[,pred_dissim := 
                                                                         predict(model_avg_delta4, se.fit = T, full = F, newdata = dissimilarity_covariates_dredge.dt_predictions_consistenttempfishinginreg)[[1]]][,pred_se :=
                                                                                                                                                                                                                 predict(model_avg_delta4, se.fit = T, full = F, newdata = dissimilarity_covariates_dredge.dt_predictions_consistenttempfishinginreg)[[2]]]
Warning: argument 'full' ignoredWarning: argument 'full' ignored
#and then with consistent temp and fishing across regions (mean of both fishing and temp)
dissimilarity_covariates_dredge.dt_predictions_consistenttempfishing <- copy(dissimilarity_covariates_dredge.dt)
dissimilarity_covariates_dredge.dt_predictions_consistenttempfishing[,summed_tonnes_scaled_byreg:=mean(summed_tonnes_scaled_byreg)][,yearly_min_bypoint_avg.scaledacrossall:=mean(yearly_min_bypoint_avg.scaledacrossall)]

dissimilarity_covariates_dredge.dt_predictions_consistenttempfishing[,pred_dissim := 
                                                                         predict(model_avg_delta4, se.fit = T, full = F, newdata = dissimilarity_covariates_dredge.dt_predictions_consistenttempfishing)[[1]]][,pred_se :=
                                                                                                                                                                                                                 predict(model_avg_delta4, se.fit = T, full = F, newdata = dissimilarity_covariates_dredge.dt_predictions_consistenttempfishing)[[2]]]
Warning: argument 'full' ignoredWarning: argument 'full' ignored
#FOR COLOR TO MATCH
#sort color link by survey name season
#alphabetical order
color_link_alpha <- setorder(color_link, survey_unit)

#exclude surveys we don't include
color_link_alpha <- color_link_alpha[survey_unit %in% unique(dissimilarity_covariates_dredge.dt_predictions$survey_unit),]

color_alpha_order <- color_link_alpha[,hex]
label_alpha_order <- color_link_alpha[,Survey_Name_Season]
  

#maintain temp and fishing
#plot
predicted_values_temp_fishing <- ggplot(dissimilarity_covariates_dredge.dt_predictions) +
  geom_point(aes(x = year, y = annual_dissimilarity_value, color = survey_unit)) +
  geom_line(aes(x = year, y = pred_dissim, color = survey_unit)) +
  geom_ribbon(aes(x = year, ymin = pred_dissim-pred_se, ymax = pred_dissim+pred_se, fill = survey_unit), alpha = 0.3) +
  scale_color_manual(values = color_alpha_order, labels = label_alpha_order, name = "Survey") +
  scale_fill_manual(values = color_alpha_order, labels = label_alpha_order, name = "Survey") +
  labs(x = "Year",y = "Average annual total\nBray Curtis dissimilarity") +
  ylim(0,1.5) +
  theme_classic() +
  ggtitle("Average model predictions")

#average temp and fishing for each region
predicted_values_temp_fishing_meantempfishinginsurvey <- ggplot(dissimilarity_covariates_dredge.dt_predictions_consistenttempfishinginreg) +
  geom_point(aes(x = year, y = annual_dissimilarity_value, color = survey_unit)) +
  geom_line(aes(x = year, y = pred_dissim, color = survey_unit)) +
  geom_ribbon(aes(x = year, ymin = pred_dissim-pred_se, ymax = pred_dissim+pred_se, fill = survey_unit), alpha = 0.3) +
  scale_color_manual(values = color_alpha_order, labels = label_alpha_order, name = "Survey") +
  scale_fill_manual(values = color_alpha_order, labels = label_alpha_order, name = "Survey") +
  labs(x = "Year",y = "Average annual total\nBray Curtis dissimilarity") +
  ylim(0,1.5) +
  theme_classic() +
  ggtitle("Average model predictions with mean\nsurvey temperature and fishing pressure")

#average temp and fishing across all regions
predicted_values_temp_fishing_meantempfishing <- ggplot(dissimilarity_covariates_dredge.dt_predictions_consistenttempfishing) +
  geom_point(aes(x = year, y = annual_dissimilarity_value, color = survey_unit)) +
  geom_line(aes(x = year, y = pred_dissim, color = survey_unit)) +
  geom_ribbon(aes(x = year, ymin = pred_dissim-pred_se, ymax = pred_dissim+pred_se, fill = survey_unit), alpha = 0.1) +
  scale_color_manual(values = color_alpha_order, labels = label_alpha_order, name = "Survey") +
  scale_fill_manual(values = color_alpha_order, labels = label_alpha_order, name = "Survey") +
  labs(x = "Year",y = "Average annual total\nBray Curtis dissimilarity") +
  ylim(0,1.5) +
  theme_classic() +
  ggtitle("Average model predictions with mean\novereall temperature and fishing pressure")

#merge plots
predicted_values_sbt_jaccard_fishing_merge <- cowplot::plot_grid(predicted_values_temp_fishing,
                                                 predicted_values_temp_fishing_meantempfishinginsurvey,
                                                 predicted_values_temp_fishing_meantempfishing,
                                                 ncol = 1)
Warning: Removed 27 rows containing missing values (`geom_line()`).Warning: no non-missing arguments to max; returning -InfWarning: no non-missing arguments to max; returning -Inf
ggsave(predicted_values_sbt_jaccard_fishing_merge, path = here::here("figures"), filename = "predicted_values_sbt_jaccard_fishing_merge.jpg", height = 30, width = 14)

Take dissimilarity values from random normal distribution for each year for each region, and then calculate slope (1000 times). Do this for: - Fishing and temperature vary interannually within surveys - Temperature is held constant (as mean over time series for a survey), but fishing varies (allows us to look at relative variance explained) - Fishing is held constant (as mean over time series for a survey), but temperature varies (allows us to look at relative variance explained) - Both fishing and temperature held constant (allows us to see role of other components of the model)

################################################################################
#full predictions
################################################################################
#table with predicted dissimilarity values and standard error of all predicted dissimilarity values (by year)
table <- dissimilarity_covariates_dredge.dt_predictions[,.(survey_unit, pred_dissim, pred_se, year)]
#0) make datatable to populate
  predicted_dissim_trends_rnormruns <- data.table()
#1) NEW PREDICTED VALUES FROM DISTRIBUTION
for (i in 1:1000){
  table[,rnorm_pred := rnorm(1, mean = pred_dissim, sd = pred_se),.(year, survey_unit)]
#2) CALCULATE LINEAR MODEL TO EXTRACT SURVEY SPECIFIC TREND VALUES
  jaccard_total_predicted_lm_singlerun <- lm(rnorm_pred ~ year*survey_unit,data = table)

  model_coefs_reduced_predictions_singlerun <- data.table(summary(jaccard_total_predicted_lm_singlerun)$coefficients)
  model_coefs_reduced_predictions_singlerun[,var := rownames(summary(jaccard_total_predicted_lm_singlerun)$coefficients)]
  
  #limit to interactions only (check this if there are any model changes!) row 2 and rows 34:64
  model_coefs_reduced_predictions_singlerun <- model_coefs_reduced_predictions_singlerun[c(2,34:64),]
  
  #adjust survey unit name by deleting beginning of string
  model_coefs_reduced_predictions_singlerun[,survey_unit := substr(var, 17, str_length(var))][var == "year",survey_unit := "AI"]
  
  #calculate interaction coefficients
  AI_estimate <- model_coefs_reduced_predictions_singlerun[1,Estimate]
  model_coefs_reduced_predictions_singlerun[1,estimate := AI_estimate]
  model_coefs_reduced_predictions_singlerun[2:32,estimate := (AI_estimate + Estimate)]
  
  predicted_dissim_trends_rnormruns <- rbind(predicted_dissim_trends_rnormruns, model_coefs_reduced_predictions_singlerun[,.(survey_unit, estimate)])
  
  print(i)
}
  
#reduce to mean and standard deviation
predicted_dissim_trends_rnormruns[,mean_dissim_coef:= mean(estimate),survey_unit][,sd_dissim := sd(estimate),.(survey_unit)]

predicted_dissim_trends_rnormruns.summary <- unique(predicted_dissim_trends_rnormruns[,.(survey_unit, mean_dissim_coef, sd_dissim)])

predicted_dissim_trends_rnormruns.summary[,pred_type := "full"]

################################################################################
#predictions with temp held constant and fishing still varying from year to year
################################################################################
#table with predicted dissimilarity values and standard error of all predicted dissimilarity values (by year)
table_constanttemp <- dissimilarity_covariates_dredge.dt_predictions_consistenttempinreg[,.(survey_unit, pred_dissim, pred_se, year)]
#0) make datatable to populate
  predicted_dissim_trends_rnormruns_constanttemp <- data.table()
#1) NEW PREDICTED VALUES FROM DISTRIBUTION
for (i in 1:1000){
  table_constanttemp[,rnorm_pred := rnorm(1, mean = pred_dissim, sd = pred_se),.(year, survey_unit)]
#2) CALCULATE LINEAR MODEL FOR SLOPE VALUES
  jaccard_total_predicted_lm_singlerun_constanttemp <- lm(rnorm_pred ~ year*survey_unit,data = table_constanttemp)

  model_coefs_reduced_predictions_singlerun_constanttemp <- data.table(summary(jaccard_total_predicted_lm_singlerun_constanttemp)$coefficients)
  model_coefs_reduced_predictions_singlerun_constanttemp[,var := rownames(summary(jaccard_total_predicted_lm_singlerun_constanttemp)$coefficients)]
  
  #limit to interactions only (check this if there are any model changes!) row 2 and rows 34:64
  model_coefs_reduced_predictions_singlerun_constanttemp <- model_coefs_reduced_predictions_singlerun_constanttemp[c(2,34:64),]
  
  #adjust survey unit name by deleting beginning of string
  model_coefs_reduced_predictions_singlerun_constanttemp[,survey_unit := substr(var, 17, str_length(var))][var == "year",survey_unit := "AI"]
  
  #calculate interaction coefficients
  AI_estimate <- model_coefs_reduced_predictions_singlerun_constanttemp[1,Estimate]
  model_coefs_reduced_predictions_singlerun_constanttemp[1,estimate := AI_estimate]
  model_coefs_reduced_predictions_singlerun_constanttemp[2:32,estimate := (AI_estimate + Estimate)]
  
  predicted_dissim_trends_rnormruns_constanttemp <- rbind(predicted_dissim_trends_rnormruns_constanttemp, model_coefs_reduced_predictions_singlerun_constanttemp[,.(survey_unit, estimate)])
  
  print(i)
}
  
#reduce to mean and standard deviation
predicted_dissim_trends_rnormruns_constanttemp[,mean_dissim_coef:= mean(estimate),survey_unit][,sd_dissim := sd(estimate),.(survey_unit)]

predicted_dissim_trends_rnormrunsconstant_temp.summary <- unique(predicted_dissim_trends_rnormruns_constanttemp[,.(survey_unit, mean_dissim_coef, sd_dissim)])

predicted_dissim_trends_rnormrunsconstant_temp.summary[,pred_type := "temp_constant"]

predicted_dissim_trends_rnormruns.summary <- rbind(predicted_dissim_trends_rnormruns.summary, predicted_dissim_trends_rnormrunsconstant_temp.summary)

################################################################################
#predictions with fishing held constant (and temperature varying)
################################################################################
#table with predicted dissimilarity values and standard error of all predicted dissimilarity values (by year)
table_constantfishing <- dissimilarity_covariates_dredge.dt_predictions_consistentfishinginreg[,.(survey_unit, pred_dissim, pred_se, year)]
#0) make datatable to populate
  predicted_dissim_trends_rnormruns_constantfishing <- data.table()
#1) NEW PREDICTED VALUES FROM DISTRIBUTION
for (i in 1:1000){
  table_constantfishing[,rnorm_pred := rnorm(1, mean = pred_dissim, sd = pred_se),.(year, survey_unit)]
#2) CALCULATE LINEAR MODEL FOR SLOPE VALUES
  jaccard_total_predicted_lm_singlerun_constantfishing <- lm(rnorm_pred ~ year*survey_unit,data = table_constantfishing)

  model_coefs_reduced_predictions_singlerun_constantfishing <- data.table(summary(jaccard_total_predicted_lm_singlerun_constantfishing)$coefficients)
  model_coefs_reduced_predictions_singlerun_constantfishing[,var := rownames(summary(jaccard_total_predicted_lm_singlerun_constantfishing)$coefficients)]
  
  #limit to interactions only (check this if there are any model changes!) row 2 and rows 34:64
  model_coefs_reduced_predictions_singlerun_constantfishing <- model_coefs_reduced_predictions_singlerun_constantfishing[c(2,34:64),]
  
  #adjust survey unit name by deleting beginning of string
  model_coefs_reduced_predictions_singlerun_constantfishing[,survey_unit := substr(var, 17, str_length(var))][var == "year",survey_unit := "AI"]
  
  #calculate interaction coefficients
  AI_estimate <- model_coefs_reduced_predictions_singlerun_constantfishing[1,Estimate]
  model_coefs_reduced_predictions_singlerun_constantfishing[1,estimate := AI_estimate]
  model_coefs_reduced_predictions_singlerun_constantfishing[2:32,estimate := (AI_estimate + Estimate)]
  
  predicted_dissim_trends_rnormruns_constantfishing <- rbind(predicted_dissim_trends_rnormruns_constantfishing, model_coefs_reduced_predictions_singlerun_constantfishing[,.(survey_unit, estimate)])
  
  print(i)
}
  
#reduce to mean and standard deviation
predicted_dissim_trends_rnormruns_constantfishing[,mean_dissim_coef:= mean(estimate),survey_unit][,sd_dissim := sd(estimate),.(survey_unit)]

predicted_dissim_trends_rnormrunsconstant_fishing.summary <- unique(predicted_dissim_trends_rnormruns_constantfishing[,.(survey_unit, mean_dissim_coef, sd_dissim)])

predicted_dissim_trends_rnormrunsconstant_fishing.summary[,pred_type := "fishing_constant"]

predicted_dissim_trends_rnormruns.summary <- rbind(predicted_dissim_trends_rnormruns.summary, predicted_dissim_trends_rnormrunsconstant_fishing.summary)


################################################################################
#predictions with both fishing and temperature held constant (variability goes to other factors we don't account for)
################################################################################
#table with predicted dissimilarity values and standard error of all predicted dissimilarity values (by year)
table_constanttempfishing <- dissimilarity_covariates_dredge.dt_predictions_consistenttempfishinginreg[,.(survey_unit, pred_dissim, pred_se, year)]
#0) make datatable to populate
  predicted_dissim_trends_rnormruns_constanttempfishing <- data.table()
#1) NEW PREDICTED VALUES FROM DISTRIBUTION
for (i in 1:1000){
  table_constanttempfishing[,rnorm_pred := rnorm(1, mean = pred_dissim, sd = pred_se),.(year, survey_unit)]
#2) CALCULATE LINEAR MODEL FOR SLOPE VALUES
  jaccard_total_predicted_lm_singlerun_constanttempfishing <- lm(rnorm_pred ~ year*survey_unit,data = table_constanttempfishing)

  model_coefs_reduced_predictions_singlerun_constanttempfishing <- data.table(summary(jaccard_total_predicted_lm_singlerun_constanttempfishing)$coefficients)
  model_coefs_reduced_predictions_singlerun_constanttempfishing[,var := rownames(summary(jaccard_total_predicted_lm_singlerun_constanttempfishing)$coefficients)]
  
  #limit to interactions only (check this if there are any model changes!) row 2 and rows 34:64
  model_coefs_reduced_predictions_singlerun_constanttempfishing <- model_coefs_reduced_predictions_singlerun_constanttempfishing[c(2,34:64),]
  
  #adjust survey unit name by deleting beginning of string
  model_coefs_reduced_predictions_singlerun_constanttempfishing[,survey_unit := substr(var, 17, str_length(var))][var == "year",survey_unit := "AI"]
  
  #calculate interaction coefficients
  AI_estimate <- model_coefs_reduced_predictions_singlerun_constanttempfishing[1,Estimate]
  model_coefs_reduced_predictions_singlerun_constanttempfishing[1,estimate := AI_estimate]
  model_coefs_reduced_predictions_singlerun_constanttempfishing[2:32,estimate := (AI_estimate + Estimate)]
  
  predicted_dissim_trends_rnormruns_constanttempfishing <- rbind(predicted_dissim_trends_rnormruns_constanttempfishing, model_coefs_reduced_predictions_singlerun_constanttempfishing[,.(survey_unit, estimate)])
  
  print(i)
}
  
#reduce to mean and standard deviation
predicted_dissim_trends_rnormruns_constanttempfishing[,mean_dissim_coef:= mean(estimate),survey_unit][,sd_dissim := sd(estimate),.(survey_unit)]

predicted_dissim_trends_rnormrunsconstant_tempfishing.summary <- unique(predicted_dissim_trends_rnormruns_constanttempfishing[,.(survey_unit, mean_dissim_coef, sd_dissim)])

predicted_dissim_trends_rnormrunsconstant_tempfishing.summary[,pred_type := "fishing_and_temp_constant"]

predicted_dissim_trends_rnormruns.summary <- rbind(predicted_dissim_trends_rnormruns.summary, predicted_dissim_trends_rnormrunsconstant_tempfishing.summary)

Plotting observed vs predicted


jaccard_fishing_temp_model_observed_predicted_dt <- jaccard_total_coefs.r[predicted_dissim_trends_rnormruns.summary, on = "survey_unit"]

jaccard_fishing_temp_model_observed_predicted_dt[,pred_lower := mean_dissim_coef-sd_dissim][,pred_upper := mean_dissim_coef+sd_dissim]

#FULL MODEL, both temperature and fishing are allowed to vary
jaccard_fishing_temp_model_observed_predicted_lm <- lm(estimate ~ mean_dissim_coef, data = jaccard_fishing_temp_model_observed_predicted_dt[pred_type == "full"])
summary(jaccard_fishing_temp_model_observed_predicted_lm) #R^2 0.56

Call:
lm(formula = estimate ~ mean_dissim_coef, data = jaccard_fishing_temp_model_observed_predicted_dt[pred_type == 
    "full"])

Residuals:
       Min         1Q     Median         3Q        Max 
-0.0021560 -0.0005673 -0.0001628  0.0002739  0.0026908 

Coefficients:
                  Estimate Std. Error t value Pr(>|t|)    
(Intercept)      4.504e-05  2.087e-04   0.216    0.831    
mean_dissim_coef 1.339e+00  2.140e-01   6.254 6.86e-07 ***
---
Signif. codes:  0 ā€˜***’ 0.001 ā€˜**’ 0.01 ā€˜*’ 0.05 ā€˜.’ 0.1 ā€˜ ’ 1

Residual standard error: 0.001179 on 30 degrees of freedom
Multiple R-squared:  0.566, Adjusted R-squared:  0.5515 
F-statistic: 39.12 on 1 and 30 DF,  p-value: 6.863e-07
(jaccard_fishing_temp_model_observed_predicted <- ggplot(jaccard_fishing_temp_model_observed_predicted_dt[pred_type == "full"]) +
  geom_errorbar(aes(x = mean_dissim_coef, ymin = lwr, ymax = upr), color = "lightgrey", linewidth = 0.4) +
  geom_errorbarh(aes(y = estimate, xmin = mean_dissim_coef-sd_dissim, xmax = mean_dissim_coef+sd_dissim), color = "lightgrey", linewidth = 0.4) +
  geom_point(aes(y = estimate, x = mean_dissim_coef)) +
  geom_smooth(aes(y = estimate, x = mean_dissim_coef), color = "darkgrey",linetype = "dotted", method = "lm") +
  geom_abline(aes(slope = 1, intercept = 0)) +
  lims(x = c(min(jaccard_fishing_temp_model_observed_predicted_dt$pred_lower),max(jaccard_fishing_temp_model_observed_predicted_dt$pred_upper))) +
  labs(y = "Observed β-diversity trend",x = "Predicted β-diversity trend\n") +
  theme_classic()
)


#fishing constant (fishing constant; temperature varies only)
jaccard_fishing_constant_model_observed_predicted_lm <- lm(estimate ~ mean_dissim_coef, data = jaccard_fishing_temp_model_observed_predicted_dt[pred_type == "fishing_constant"])
summary(jaccard_fishing_constant_model_observed_predicted_lm) 

Call:
lm(formula = estimate ~ mean_dissim_coef, data = jaccard_fishing_temp_model_observed_predicted_dt[pred_type == 
    "fishing_constant"])

Residuals:
       Min         1Q     Median         3Q        Max 
-0.0038730 -0.0007399  0.0001136  0.0011372  0.0025014 

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)      -0.0001537  0.0002541  -0.605 0.549774    
mean_dissim_coef  1.7942377  0.4072227   4.406 0.000124 ***
---
Signif. codes:  0 ā€˜***’ 0.001 ā€˜**’ 0.01 ā€˜*’ 0.05 ā€˜.’ 0.1 ā€˜ ’ 1

Residual standard error: 0.001394 on 30 degrees of freedom
Multiple R-squared:  0.3929,    Adjusted R-squared:  0.3726 
F-statistic: 19.41 on 1 and 30 DF,  p-value: 0.0001238
#Temperature as a predictor, not fishing = R^2 = 0.40 (drop in 16% of variance explained when you lose fishing as predictor)

(jaccard_fishing_constant_model_observed_predicted <- ggplot(jaccard_fishing_temp_model_observed_predicted_dt[pred_type == "fishing_constant"]) +
geom_errorbar(aes(x = mean_dissim_coef, ymin = lwr, ymax = upr), color = "lightgrey", linewidth = 0.4) +
  geom_errorbarh(aes(y = estimate, xmin = mean_dissim_coef-sd_dissim, xmax = mean_dissim_coef+sd_dissim), color = "lightgrey", linewidth = 0.4) +
  geom_point(aes(y = estimate, x = mean_dissim_coef)) +
    geom_smooth(aes(y = estimate, x = mean_dissim_coef), color = "darkgrey",linetype = "dotted", method = "lm") +
  geom_abline(aes(slope = 1, intercept = 0)) +
      lims(x = c(min(jaccard_fishing_temp_model_observed_predicted_dt$pred_lower),max(jaccard_fishing_temp_model_observed_predicted_dt$pred_upper))) +
  labs(y = "Observed β-diversity trend",x = "Predicted β-diversity trend\n(temperature varies fishing constant)") +
  theme_classic()
)


#temp constant (fishing only; temperature constant)
jaccard_temperature_constant_model_observed_predicted_lm <- lm(estimate ~ mean_dissim_coef, data = jaccard_fishing_temp_model_observed_predicted_dt[pred_type == "temp_constant"])
summary(jaccard_temperature_constant_model_observed_predicted_lm) #0.26 Drop in 30% of variance explained when you lose temperature as a predictor

Call:
lm(formula = estimate ~ mean_dissim_coef, data = jaccard_fishing_temp_model_observed_predicted_dt[pred_type == 
    "temp_constant"])

Residuals:
       Min         1Q     Median         3Q        Max 
-0.0025579 -0.0007197 -0.0002048  0.0003897  0.0042665 

Coefficients:
                  Estimate Std. Error t value Pr(>|t|)   
(Intercept)      0.0001684  0.0002729   0.617  0.54192   
mean_dissim_coef 0.8098204  0.2508463   3.228  0.00301 **
---
Signif. codes:  0 ā€˜***’ 0.001 ā€˜**’ 0.01 ā€˜*’ 0.05 ā€˜.’ 0.1 ā€˜ ’ 1

Residual standard error: 0.001542 on 30 degrees of freedom
Multiple R-squared:  0.2578,    Adjusted R-squared:  0.2331 
F-statistic: 10.42 on 1 and 30 DF,  p-value: 0.00301
(jaccard_temperature_constant_model_observed_predicted <- ggplot(jaccard_fishing_temp_model_observed_predicted_dt[pred_type == "temp_constant"]) +
  geom_errorbar(aes(x = mean_dissim_coef, ymin = lwr, ymax = upr), color = "lightgrey", linewidth = 0.4) +
  geom_errorbarh(aes(y = estimate, xmin = mean_dissim_coef-sd_dissim, xmax = mean_dissim_coef+sd_dissim), color = "lightgrey", linewidth = 0.4) +
  geom_point(aes(y = estimate, x = mean_dissim_coef)) +
    geom_smooth(aes(y = estimate, x = mean_dissim_coef), color = "darkgrey",linetype = "dotted", method = "lm") +
  geom_abline(aes(slope = 1, intercept = 0)) +
      lims(x = c(min(jaccard_fishing_temp_model_observed_predicted_dt$pred_lower),max(jaccard_fishing_temp_model_observed_predicted_dt$pred_upper))) +
  labs(y = "Observed β-diversity trend",x = "Predicted β-diversity trend\n(fishing varies temperature constant)") +
  theme_classic()
)


#both temperature and fish held constant
jaccard_fishing_temp_model_observed_predicted_tempfishconstantinsurvey_lm <- lm(estimate ~ mean_dissim_coef, data = jaccard_fishing_temp_model_observed_predicted_dt[pred_type == "fishing_and_temp_constant"])
summary(jaccard_fishing_temp_model_observed_predicted_tempfishconstantinsurvey_lm) #%20 #drop of 36 from full

Call:
lm(formula = estimate ~ mean_dissim_coef, data = jaccard_fishing_temp_model_observed_predicted_dt[pred_type == 
    "fishing_and_temp_constant"])

Residuals:
       Min         1Q     Median         3Q        Max 
-0.0027797 -0.0008842 -0.0002533  0.0008447  0.0037051 

Coefficients:
                  Estimate Std. Error t value Pr(>|t|)  
(Intercept)      5.513e-05  2.846e-04   0.194   0.8477  
mean_dissim_coef 1.700e+00  6.284e-01   2.706   0.0111 *
---
Signif. codes:  0 ā€˜***’ 0.001 ā€˜**’ 0.01 ā€˜*’ 0.05 ā€˜.’ 0.1 ā€˜ ’ 1

Residual standard error: 0.001604 on 30 degrees of freedom
Multiple R-squared:  0.1962,    Adjusted R-squared:  0.1694 
F-statistic: 7.322 on 1 and 30 DF,  p-value: 0.01113
(jaccard_fishing_temp_model_observed_predicted_tempfishconstantinsurvey <- ggplot(jaccard_fishing_temp_model_observed_predicted_dt[pred_type == "fishing_and_temp_constant"]) +
geom_errorbar(aes(x = mean_dissim_coef, ymin = lwr, ymax = upr), color = "lightgrey", linewidth = 0.4) +
  geom_errorbarh(aes(y = estimate, xmin = mean_dissim_coef-sd_dissim, xmax = mean_dissim_coef+sd_dissim), color = "lightgrey", linewidth = 0.4) +
  geom_point(aes(y = estimate, x = mean_dissim_coef)) +
    geom_smooth(aes(y = estimate, x = mean_dissim_coef), color = "darkgrey",linetype = "dotted", method = "lm")+
  geom_abline(aes(slope = 1, intercept = 0)) +
      lims(x = c(min(jaccard_fishing_temp_model_observed_predicted_dt$pred_lower),max(jaccard_fishing_temp_model_observed_predicted_dt$pred_upper))) +
  labs(y = "Observed β-diversity trend",x = "Predicted β-diversity trend\n(fishing and temperature constant)") +
  theme_classic()
)


#merge
jaccard_fishing_sbt_model_observed_predicted_merge <- plot_grid(jaccard_fishing_temp_model_observed_predicted + theme(plot.margin = unit(c(0.1,0.3,0.1,0.1),"cm")),
                                                                     jaccard_fishing_constant_model_observed_predicted + theme(plot.margin = unit(c(0.1,0.3,0.1,0.1),"cm")),
                                                                     jaccard_temperature_constant_model_observed_predicted + theme(plot.margin = unit(c(0.1,0.3,0.1,0.1),"cm")),
                                                                     jaccard_fishing_temp_model_observed_predicted_tempfishconstantinsurvey + theme(plot.margin = unit(c(0.1,0.3,0.1,0.1),"cm")), ncol = 2, labels = c("a.","b.","c.","d."))
`geom_smooth()` using formula = 'y ~ x'`geom_smooth()` using formula = 'y ~ x'`geom_smooth()` using formula = 'y ~ x'`geom_smooth()` using formula = 'y ~ x'
ggsave(jaccard_fishing_sbt_model_observed_predicted_merge, path = here::here("figures"),filename = "jaccard_fishing_sbt_model_observed_predicted_merge.jpg", height =6, width = 8)

NA
NA

Let’s visualize model coefficients with temperature and fishing (similar to figure 2) model_avg_values

Plot all other coefficients in averaged model

model_avg_values.nonfishortemp <- model_avg_values[c(2,6,102:106),]

#mark significance
model_avg_values.nonfishortemp[,Significant := ifelse((coef-se > 0 & coef+se > 0) | (coef-se < 0 & coef+se < 0),T,F)]

#more helpful names for variables
model_avg_values.nonfishortemp[,Variable := c("Area","Species count","Depth","Number of tows","Latitude","Depth range","Latitude range")]

#make factor with order
model_avg_values.nonfishortemp[,Variable := factor(Variable, levels = c("Area","Species count","Number of tows","Depth","Depth range","Latitude","Latitude range"))]


#plot
all_avg_model_coef <- ggplot() + 
geom_point(data = model_avg_values.nonfishortemp, aes(x = Variable, y = coef, color = Significant)) +  
geom_errorbar(data = model_avg_values.nonfishortemp, aes(x = Variable, ymin = coef-se, ymax = coef+se, color = Significant), width = 0) +
  scale_color_manual(values = c("darkgrey","black")) +
geom_hline(yintercept = 0) +
scale_x_discrete(limits = rev) +
  labs(y = "Coefficient", x = "\n\n\n") +
coord_flip() +
theme_classic()

#plot
all_but_lat_avg_model_coef <- ggplot() + 
geom_point(data = model_avg_values.nonfishortemp[Variable == "Latitude"], aes(x = Variable, y = coef, color = Significant)) +  
geom_errorbar(data = model_avg_values.nonfishortemp[Variable == "Latitude"], aes(x = Variable, ymin = coef-se, ymax = coef+se, color = Significant), width = 0) +
  scale_color_manual(values = c("darkgrey","black")) +
geom_hline(yintercept = 0) +
scale_x_discrete(limits = rev) +
  labs(y = "Coefficient", x = "Model variable") +
coord_flip() +
theme_classic()

#plot
lat_avg_model_coef <- ggplot() + 
geom_point(data = model_avg_values.nonfishortemp[Variable != "Latitude"], aes(x = Variable, y = coef, color = Significant)) +  
geom_errorbar(data = model_avg_values.nonfishortemp[Variable != "Latitude"], aes(x = Variable, ymin = coef-se, ymax = coef+se, color = Significant), width = 0) +
  scale_color_manual(values = c("darkgrey","black")) +
geom_hline(yintercept = 0) +
scale_x_discrete(limits = rev) +
  labs(y = "Coefficient", x = "Model variable") +
coord_flip() +
theme_classic()

#merge into single plot

model_coef_summary_sbt_jaccard <- cowplot::plot_grid(sbt_fishing_avg_model_coef+theme(legend.position = "null", axis.title.x = element_blank()),all_avg_model_coef+theme(legend.position = "null"), ncol = 1, labels = c("  a.                                                      b.","        c."), label_y = 0.99, rel_heights = c(3,1))

ggsave(model_coef_summary_sbt_jaccard, path = here::here("figures"),filename = "model_coef_summary_sbt_jaccard.jpg", height = 6.5, width = 8, unit = "in")

#IF WE ACTUALLY USE THIS, NEED TO UPDATE ##Show intercepts by region and season # #{r} # ##survey intercepts #survey_intercepts <- model_avg_values[c(1,8:38),.(coef_name, coef, se)] #survey_intercepts[1,survey_unit := "AI"][1,coef_true := coef] #survey_intercepts[2:32,survey_unit := substr(coef_name, 12, str_length(coef_name))][2:32,coef_true := survey_intercepts[1,coef_true]+coef] #survey_intercepts <- color_link[survey_intercepts, on = "survey_unit"] #survey_intercepts[,Survey_Name_Season := reorder(Survey_Name_Season, coef_true)] # # ##season_intercepts #season_intercepts <- model_avg_values[c(1,3:5),.(coef_name, coef, se)] #season_intercepts[1,season := "Spring"][1,coef_true := coef] #season_intercepts[2:4,season := substr(coef_name, 7, str_length(coef_name))][2:4,coef_true := season_intercepts[1,coef_true]+coef] #season_intercepts[,season := reorder(season, coef_true)] # # ##survey intercepts #survey_model_coef <- ggplot() + #geom_point(data = survey_intercepts, aes(x = Survey_Name_Season, y = coef_true)) + #geom_errorbar(data = survey_intercepts, aes(x = Survey_Name_Season, ymin = coef_true-se, ymax = coef_true+se), width = 0) + #scale_x_discrete(limits = rev) + ## ylim(0.35,1) + # labs(y = "Intercept", x = "") + #coord_flip() + #theme_classic() # ##season intercepts #season_model_coef <- ggplot() + #geom_point(data = season_intercepts, aes(x = season, y = coef_true)) + #geom_errorbar(data = season_intercepts, aes(x = season, ymin = coef_true-se, ymax = coef_true+se), width = 0) + #scale_x_discrete(limits = rev) + # # ylim(0.35,1) + # labs(y = "Intercept", x = "") + #coord_flip() + #theme_classic() # ##merge into single plot # #model_intercept_jaccard <- cowplot::plot_grid(survey_model_coef+theme(axis.title.x = element_blank()), # season_model_coef, ncol = 1, labels = c("a.","b."), label_y = 0.99, rel_heights = c(3,1), align = "v") # #ggsave(model_intercept_jaccard, path = here::here("figures"),filename = "model_intercept_jaccard.jpg", height = 6.5, width = 6.5, unit = "in") # # # ##

LS0tCnRpdGxlOiAiTW9kZWwgYW5udWFsIGRpc3NpbWlsYXJpdHkgd2l0aCB0ZW1wZXJhdHVyZSwgZmlzaGluZywgYW5kIHN1cnZleSBpZGVudGl0eSIKb3V0cHV0OiBodG1sX25vdGVib29rCmF1dGhvcjogWm/DqyBKLiBLaXRjaGVsCmRhdGU6IE1heSA2LCAyMDI0Ci0tLQoKU2NyaXB0IDggZm9yIEtpdGNoZWwgZXQgYWwuIDIwMjQgaW4gcHJlcCB0YXhvbm9taWMgZGl2ZXJzaXR5IG1hbnVzY3JpcHQuCgoKYGBge3Igc2V0dXB9CmxpYnJhcnkoZGF0YS50YWJsZSkKbGlicmFyeShNdU1JbikKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGNvd3Bsb3QpCmxpYnJhcnkobG1lNCkKbGlicmFyeShzdHJpbmdyKQpsaWJyYXJ5KG5sbWUpCgojcHVsbCBpbiBmdW5jdGlvbiB0byBjYWxjdWxhdGUgbW9kZWwgZXN0aW1hdGVzIGFuZCBzdGFuZGFyZCBlcnJvcnMKc291cmNlKGhlcmU6OmhlcmUoImFuYWx5c2lzX2NvZGUiLCJleHRyYWN0X2NvZWZmaWNpZW50c19mdW5jdGlvbi5SIikpCmBgYAoKIyMjUHJlZGljdHMgYW5udWFsIGRpc3NpbWlsYXJpdHkgd2l0aCBhbm51YWwgY2hhcmFjdGVyaXN0aWNzLCB0ZW1wZXJhdHVyZSBhbmQgZmlzaGluZyB2YWx1ZXMKClB1bGwgaW4KLSByZWdpb24gYXJlYXMgKGlmIG5vdCBhbHJlYWR5IGxvYWRlZCkKLSByZWdpb24gY2hhcmFjdGVyaXN0aWNzIChpZiBub3QgYWxyZWFkeSBsb2FkZWQpOyBzYXZlUkRTKEZpc2hHbG9iX3JpY2huZXNzX3llYXJfc3VydmV5LCBmaWxlID0gaGVyZTo6aGVyZSgib3V0cHV0IiwiRmlzaEdsb2JfcmljaG5lc3NfeWVhcl9zdXJ2ZXkuUmRzIikpCi0gZmlzaGluZyAoaWYgbm90IGFscmVhZHkgbG9hZGVkKQotIHRlbXAgKGlmIG5vdCBhbHJlYWR5IGxvYWRlZCkKCgoKYGBge3J9CiNwaHlzaWNhbCBhcmVhIGJ5IHllYXIKcmVnaW9uX2FyZWFfYnl5ZWFyIDwtIGZyZWFkKGhlcmU6OmhlcmUoIm91dHB1dCIsInJlZ2lvbl9hcmVhX2J5eWVhci5jc3YiKSkKCiNtZXJnZWQgZmlzaGluZywgdGVtcCwgZGlzc2ltaWxhcml0aWVzCmRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmcgPC0gZnJlYWQoaGVyZTo6aGVyZSgib3V0cHV0IiwiZGlzc2ltaWxhcml0aWVzX3RlbXBfZmlzaGluZy5jc3YiKSkKCiNjb21iaW5lCmRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfYXJlYSA8LSBkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nW3JlZ2lvbl9hcmVhX2J5eWVhciwgb24gPSBjKCJzdXJ2ZXlfdW5pdCIsInllYXIiKV0KCiNvbmx5IGphY2NhcmQgZm9yIHRoZXNlIGFuYWx5c2VzCmRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfYXJlYS5qYWNjYXJkIDwtIGRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfYXJlYVtkaXNzaW1pbGFyaXR5X21ldHJpYyA9PSAiamFjY2FyZF9kaXNzaW1pbGFyaXR5X2luZGV4X2JpbmFyeSIsXQpgYGAKCkFkZCBpbiBzZWFzb24KYGBge3J9CiNsb2FkIHVwIGp1bGlhbiBkYXlzCmRhdGVzX3JlZ2lvbnMgPC0gcmVhZFJEUyhoZXJlOjpoZXJlKCJvdXRwdXQiLCJkYXRlc19yZWdpb25zLnJkcyIpKQoKI21vc3QgY29tbW9uIHNlYXNvbiBwZXIgeWVhcgojIEZ1bmN0aW9uIHRvIGdldCB0aGUgbW9zdCBmcmVxdWVudCB2YWx1ZQpnZXRfbW9kZSA8LSBmdW5jdGlvbih4KSB7CiAgdXggPC0gdW5pcXVlKHgpCiAgdXhbd2hpY2gubWF4KHRhYnVsYXRlKG1hdGNoKHgsIHV4KSkpXQp9CgojIEFwcGx5IHRoZSBmdW5jdGlvbiB0byBlYWNoIGdyb3VwCmRhdGVzX3JlZ2lvbnMuciA8LSBkYXRlc19yZWdpb25zWywgLihzZWFzb24gPSBnZXRfbW9kZShzZWFzb24pKSwgYnkgPSBjKCJzdXJ2ZXlfdW5pdCIsInllYXIiKV0KCgojbWVyZ2UKZGlzc2ltaWxhcml0aWVzX3RlbXBfZmlzaGluZ19hcmVhLmphY2NhcmQgPC0gZGF0ZXNfcmVnaW9ucy5yW2Rpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfYXJlYS5qYWNjYXJkLCBvbiA9IGMoInN1cnZleV91bml0IiwieWVhciIpXQpgYGAKCiAKUHVsbCBpbiBwYWxldHRlIGFuZCBuYW1lIGhlbHBlcgpgYGB7cn0Kc291cmNlKGhlcmU6OmhlcmUoImFuYWx5c2lzX2NvZGUiLCJjb2xvcl9saW5rcy5SIikpCmBgYAoKUHVsbCBpbiBvYnNlcnZlZCB0cmVuZCB2YWx1ZXMKYGBge3J9CmphY2NhcmRfdG90YWxfY29lZnMuciA8LSBmcmVhZChoZXJlOjpoZXJlKCJvdXRwdXQiLCJqYWNjYXJkX3RvdGFsX2NvZWZzLnIuY3N2IikpCmBgYAoKUGxvdCBmaXNoaW5nIGFuZCB0ZW1wZXJhdHVyZSB2cy4gdGltZSBmb3IgYWxsIHJlZ2lvbnMKYGBge3J9CiMjIyMjIyNURU1QRVJBVFVSRQoKI3NldCBvcmRlciBieSBzdXJ2ZXkgdW5pdCBmb3IgcGxvdHRpbmcKYWxsX3N1cnZleXMgPC0gbGV2ZWxzKGFzLmZhY3RvcihkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX2FyZWEuamFjY2FyZCRzdXJ2ZXlfdW5pdCkpCnNldG9yZGVyKGRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfYXJlYS5qYWNjYXJkLCBzdXJ2ZXlfdW5pdCkKCmRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfYXJlYS5qYWNjYXJkWyxTdXJ2ZXlfTmFtZV9TZWFzb246PWZhY3RvcihTdXJ2ZXlfTmFtZV9TZWFzb24sIGxldmVscyA9IHVuaXF1ZShkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX2FyZWEuamFjY2FyZCRTdXJ2ZXlfTmFtZV9TZWFzb24pLCBvcmRlcmVkID0gVCldCgooc2J0X3RpbWVfc3VydmV5X2ZhY2V0XzFfMjAgPC0gZ2dwbG90KGRhdGEgPSBkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX2FyZWEuamFjY2FyZFtzdXJ2ZXlfdW5pdCAlaW4lIGFsbF9zdXJ2ZXlzWzE6MjBdICYgeWVhciA+IDE5NzldKSArCiAgbGFicyh5ID0gIk1lYW4gYm90dG9tIHRlbXBlcmF0dXJlICjLmkMpIiwgIHggPSAiWWVhciIpICsKICBnZW9tX3BvaW50KGFlcyh5ID0gYXMubnVtZXJpYyh5ZWFybHlfbWVhbl9ieXBvaW50X2F2ZyksIHggPSB5ZWFyKSwgYWxwaGEgPSAwLjMpICsKICBnZW9tX3Ntb290aChhZXMoeSA9IGFzLm51bWVyaWMoeWVhcmx5X21lYW5fYnlwb2ludF9hdmcpLCB4ID0geWVhciksIG1ldGhvZCA9ICJsbSIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gfiBheGlzVGlja3MoLiwgbG9nID0gRkFMU0UpKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNykpICsKICBmYWNldF93cmFwKH5TdXJ2ZXlfTmFtZV9TZWFzb24sIHNjYWxlcz0gImZyZWUiLCBuY29sID0gNCkpCgpnZ3NhdmUoc2J0X3RpbWVfc3VydmV5X2ZhY2V0XzFfMjAsIHBhdGggPSBoZXJlOjpoZXJlKCJmaWd1cmVzIiksIGZpbGVuYW1lID0gInNidF90aW1lX3N1cnZleV9mYWNldF8xXzIwLmpwZyIsIGhlaWdodCA9IDEyLCB3aWR0aCA9OSkKCihzYnRfdGltZV9zdXJ2ZXlfZmFjZXRfMjFfMzQgPC0gZ2dwbG90KGRhdGEgPSBkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX2FyZWEuamFjY2FyZFtzdXJ2ZXlfdW5pdCAlaW4lIGFsbF9zdXJ2ZXlzWzIxOjM0XSAmIHllYXIgPiAxOTc5XSkgKwogIGxhYnMoeSA9ICJNZWFuIGJvdHRvbSB0ZW1wZXJhdHVyZSAoy5pDKSIsICB4ID0gIlllYXIiKSArCiAgZ2VvbV9wb2ludChhZXMoeSA9IGFzLm51bWVyaWMoeWVhcmx5X21lYW5fYnlwb2ludF9hdmcpLCB4ID0geWVhciksIGFscGhhID0gMC4zKSArCiAgZ2VvbV9zbW9vdGgoYWVzKHkgPSBhcy5udW1lcmljKHllYXJseV9tZWFuX2J5cG9pbnRfYXZnKSwgeCA9IHllYXIpLCBtZXRob2QgPSAibG0iKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IH4gYXhpc1RpY2tzKC4sIGxvZyA9IEZBTFNFKSkgKwogIHRoZW1lX2NsYXNzaWMoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDcpKSArCiAgZmFjZXRfd3JhcCh+U3VydmV5X05hbWVfU2Vhc29uLCBzY2FsZXM9ICJmcmVlIiwgbmNvbCA9IDQpKQoKZ2dzYXZlKHNidF90aW1lX3N1cnZleV9mYWNldF8yMV8zNCwgcGF0aCA9IGhlcmU6OmhlcmUoImZpZ3VyZXMiKSwgZmlsZW5hbWUgPSAic2J0X3RpbWVfc3VydmV5X2ZhY2V0XzIxXzM0LmpwZyIsIGhlaWdodCA9IDEyLCB3aWR0aCA9OSkKCiMjIyMjIyNGSVNISU5HCgpkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX2FyZWEuamFjY2FyZC5jYyA8LSBkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX2FyZWEuamFjY2FyZFtjb21wbGV0ZS5jYXNlcyhkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX2FyZWEuamFjY2FyZFssc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWddKSxdCgooZmlzaGluZ190aW1lX3N1cnZleV9mYWNldF8xXzIwIDwtIGdncGxvdChkYXRhID0gZGlzc2ltaWxhcml0aWVzX3RlbXBfZmlzaGluZ19hcmVhLmphY2NhcmQuY2Nbc3VydmV5X3VuaXQgJWluJSBhbGxfc3VydmV5c1sxOjIwXSAmIHllYXIgPiAxOTc5XSkgKwogIGxhYnMoeSA9ICJSZWxhdGl2ZSBmaXNoaW5nIGNhdGNoIiwgIHggPSAiWWVhciIpICsKICBnZW9tX3BvaW50KGFlcyh5ID0gc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWcsIHggPSB5ZWFyKSwgYWxwaGEgPSAwLjMpICsKICBnZW9tX3Ntb290aChhZXMoeSA9IHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnLCB4ID0geWVhciksIG1ldGhvZCA9ICJsbSIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gfiBheGlzVGlja3MoLiwgbG9nID0gRkFMU0UpKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNykpICsKICBmYWNldF93cmFwKH5TdXJ2ZXlfTmFtZV9TZWFzb24sIHNjYWxlcz0gImZyZWUiLCBuY29sID0gNCkpCgpnZ3NhdmUoZmlzaGluZ190aW1lX3N1cnZleV9mYWNldF8xXzIwLCBwYXRoID0gaGVyZTo6aGVyZSgiZmlndXJlcyIpLCBmaWxlbmFtZSA9ICJmaXNoaW5nX3RpbWVfc3VydmV5X2ZhY2V0XzFfMjAuanBnIiwgaGVpZ2h0ID0gMTIsIHdpZHRoID05KQoKKGZpc2hpbmdfdGltZV9zdXJ2ZXlfZmFjZXRfMjFfMzQgPC0gZ2dwbG90KGRhdGEgPSBkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX2FyZWEuamFjY2FyZC5jY1tzdXJ2ZXlfdW5pdCAlaW4lIGFsbF9zdXJ2ZXlzW2MoMjE6MzQpXSAmIHllYXIgPiAxOTc5XSkgKwogIGxhYnMoeSA9ICJSZWxhdGl2ZSBmaXNoaW5nIGNhdGNoIiwgIHggPSAiWWVhciIpICsKICBnZW9tX3BvaW50KGFlcyh5ID0gc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWcsIHggPSB5ZWFyKSwgYWxwaGEgPSAwLjMpICsKICBnZW9tX3Ntb290aChhZXMoeSA9IHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnLCB4ID0geWVhciksIG1ldGhvZCA9ICJsbSIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gfiBheGlzVGlja3MoLiwgbG9nID0gRkFMU0UpKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gNykpICsKICBmYWNldF93cmFwKH5TdXJ2ZXlfTmFtZV9TZWFzb24sIHNjYWxlcz0gImZyZWUiLCBuY29sID0gNCkpCgpnZ3NhdmUoZmlzaGluZ190aW1lX3N1cnZleV9mYWNldF8yMV8zNCwgcGF0aCA9IGhlcmU6OmhlcmUoImZpZ3VyZXMiKSwgZmlsZW5hbWUgPSAiZmlzaGluZ190aW1lX3N1cnZleV9mYWNldF8yMV8zNC5qcGciLCBoZWlnaHQgPSAxMiwgd2lkdGggPTkpCgoKYGBgCgpQbG90IGZpc2hpbmcgYW5kIHRlbXBlcmF0dXJlIHZzLiBkaXNzaW1pbGFyaXR5IGZvciBhbGwgcmVnaW9ucwpgYGB7cn0KIyMjIyNNRUFOIFRFTVAKKHByZWRzX3NidF9tZWFuX3RlbXBfc3VydmV5X2ZhY2V0XzFfMjAgPC0gZ2dwbG90KGRhdGEgPSBkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX2FyZWEuamFjY2FyZFtzdXJ2ZXlfdW5pdCAlaW4lIGFsbF9zdXJ2ZXlzWzE6MjBdICYgeWVhciA+IDE5NzldKSArCiAgbGFicyh4ID0gIk1lYW4gYm90dG9tIHRlbXBlcmF0dXJlICjLmkMpIiwgIHkgPSAizrItZGl2ZXJzaXR5IikgKwogIGdlb21fcG9pbnQoYWVzKHggPSBhcy5udW1lcmljKHllYXJseV9tZWFuX2J5cG9pbnRfYXZnKSwgeSA9IGFubnVhbF9kaXNzaW1pbGFyaXR5X3ZhbHVlKSwgYWxwaGEgPSAwLjMpICsKICBnZW9tX3Ntb290aChhZXMoeCA9IGFzLm51bWVyaWMoeWVhcmx5X21lYW5fYnlwb2ludF9hdmcpLCB5ID0gYW5udWFsX2Rpc3NpbWlsYXJpdHlfdmFsdWUpLCBtZXRob2QgPSAibG0iKSArCiAgZmFjZXRfd3JhcCh+U3VydmV5X05hbWVfU2Vhc29uLCBzY2FsZXM9ICJmcmVlIiwgbmNvbCA9IDQpICsKICB0aGVtZV9jbGFzc2ljKCkpCgpnZ3NhdmUocHJlZHNfc2J0X21lYW5fdGVtcF9zdXJ2ZXlfZmFjZXRfMV8yMCwgcGF0aCA9IGhlcmU6OmhlcmUoImZpZ3VyZXMiKSwgZmlsZW5hbWUgPSAicHJlZHNfc2J0X21lYW5fdGVtcF9zdXJ2ZXlfZmFjZXRfMV8yMC5qcGciLCBoZWlnaHQgPSAxMiwgd2lkdGggPTkpCgoocHJlZHNfc2J0X21lYW5fdGVtcF9zdXJ2ZXlfZmFjZXRfMjFfMzQgPC0gZ2dwbG90KGRhdGEgPSBkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX2FyZWEuamFjY2FyZFtzdXJ2ZXlfdW5pdCAlaW4lIGFsbF9zdXJ2ZXlzWzIxOjM0XSAmIHllYXIgPiAxOTc5XSkgKwogIGxhYnMoeCA9ICJNZWFuIGJvdHRvbSB0ZW1wZXJhdHVyZSAoy5pDKSIsICB5ID0gIs6yLWRpdmVyc2l0eSIpICsKICBnZW9tX3BvaW50KGFlcyh4ID0gYXMubnVtZXJpYyh5ZWFybHlfbWVhbl9ieXBvaW50X2F2ZyksIHkgPSBhbm51YWxfZGlzc2ltaWxhcml0eV92YWx1ZSksIGFscGhhID0gMC4zKSArCiAgZ2VvbV9zbW9vdGgoYWVzKHggPSBhcy5udW1lcmljKHllYXJseV9tZWFuX2J5cG9pbnRfYXZnKSwgeSA9IGFubnVhbF9kaXNzaW1pbGFyaXR5X3ZhbHVlKSwgbWV0aG9kID0gImxtIikgKwogIGZhY2V0X3dyYXAoflN1cnZleV9OYW1lX1NlYXNvbiwgc2NhbGVzPSAiZnJlZSIsIG5jb2wgPSA0KSArCiAgdGhlbWVfY2xhc3NpYygpKQoKZ2dzYXZlKHByZWRzX3NidF9tZWFuX3RlbXBfc3VydmV5X2ZhY2V0XzIxXzM0LCBwYXRoID0gaGVyZTo6aGVyZSgiZmlndXJlcyIpLCBmaWxlbmFtZSA9ICJwcmVkc19zYnRfbWVhbl90ZW1wX3N1cnZleV9mYWNldF8yMV8zNC5qcGciLCBoZWlnaHQgPSAxMiwgd2lkdGggPTkpCgojIyMjI01JTklNVU0gVEVNUAoocHJlZHNfc2J0X21pbl90ZW1wX3N1cnZleV9mYWNldF8xXzIwIDwtIGdncGxvdChkYXRhID0gZGlzc2ltaWxhcml0aWVzX3RlbXBfZmlzaGluZ19hcmVhLmphY2NhcmRbc3VydmV5X3VuaXQgJWluJSBhbGxfc3VydmV5c1sxOjIwXSAmIHllYXIgPiAxOTc5XSkgKwogIGxhYnMoeCA9ICJNaW5pbXVtIGJvdHRvbSB0ZW1wZXJhdHVyZSAoy5pDKSIsICB5ID0gIs6yLWRpdmVyc2l0eSIpICsKICBnZW9tX3BvaW50KGFlcyh4ID0gYXMubnVtZXJpYyh5ZWFybHlfbWluX2J5cG9pbnRfYXZnKSwgeSA9IGFubnVhbF9kaXNzaW1pbGFyaXR5X3ZhbHVlKSwgYWxwaGEgPSAwLjMpICsKICBnZW9tX3Ntb290aChhZXMoeCA9IGFzLm51bWVyaWMoeWVhcmx5X21pbl9ieXBvaW50X2F2ZyksIHkgPSBhbm51YWxfZGlzc2ltaWxhcml0eV92YWx1ZSksIG1ldGhvZCA9ICJsbSIpICsKICBmYWNldF93cmFwKH5TdXJ2ZXlfTmFtZV9TZWFzb24sIHNjYWxlcz0gImZyZWUiLCBuY29sID0gNCkgKwogIHRoZW1lX2NsYXNzaWMoKSkKCmdnc2F2ZShwcmVkc19zYnRfbWluX3RlbXBfc3VydmV5X2ZhY2V0XzFfMjAsIHBhdGggPSBoZXJlOjpoZXJlKCJmaWd1cmVzIiksIGZpbGVuYW1lID0gInByZWRzX3NidF9taW5fdGVtcF9zdXJ2ZXlfZmFjZXRfMV8yMC5qcGciLCBoZWlnaHQgPSAxMiwgd2lkdGggPTkpCgoocHJlZHNfc2J0X21pbl90ZW1wX3N1cnZleV9mYWNldF8yMV8zNCA8LSBnZ3Bsb3QoZGF0YSA9IGRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfYXJlYS5qYWNjYXJkW3N1cnZleV91bml0ICVpbiUgYWxsX3N1cnZleXNbMjE6MzRdICYgeWVhciA+IDE5NzldKSArCiAgbGFicyh4ID0gIk1pbmltdW0gYm90dG9tIHRlbXBlcmF0dXJlICjLmkMpIiwgIHkgPSAizrItZGl2ZXJzaXR5IikgKwogIGdlb21fcG9pbnQoYWVzKHggPSBhcy5udW1lcmljKHllYXJseV9taW5fYnlwb2ludF9hdmcpLCB5ID0gYW5udWFsX2Rpc3NpbWlsYXJpdHlfdmFsdWUpLCBhbHBoYSA9IDAuMykgKwogIGdlb21fc21vb3RoKGFlcyh4ID0gYXMubnVtZXJpYyh5ZWFybHlfbWluX2J5cG9pbnRfYXZnKSwgeSA9IGFubnVhbF9kaXNzaW1pbGFyaXR5X3ZhbHVlKSwgbWV0aG9kID0gImxtIikgKwogIGZhY2V0X3dyYXAoflN1cnZleV9OYW1lX1NlYXNvbiwgc2NhbGVzPSAiZnJlZSIsIG5jb2wgPSA0KSArCiAgdGhlbWVfY2xhc3NpYygpKQoKZ2dzYXZlKHByZWRzX3NidF9taW5fdGVtcF9zdXJ2ZXlfZmFjZXRfMjFfMzQsIHBhdGggPSBoZXJlOjpoZXJlKCJmaWd1cmVzIiksIGZpbGVuYW1lID0gInByZWRzX3NidF9taW5fdGVtcF9zdXJ2ZXlfZmFjZXRfMjFfMzQuanBnIiwgaGVpZ2h0ID0gMTIsIHdpZHRoID05KQoKIyMjIyMjI0ZJU0hJTkcKCmRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfYXJlYS5qYWNjYXJkLmNjIDwtIGRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfYXJlYS5qYWNjYXJkW2NvbXBsZXRlLmNhc2VzKGRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfYXJlYS5qYWNjYXJkWyxzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZ10pLF0KCihwcmVkc19zYnRfbWVhbl9maXNoaW5nX3N1cnZleV9mYWNldF8xXzIwIDwtIGdncGxvdChkYXRhID0gZGlzc2ltaWxhcml0aWVzX3RlbXBfZmlzaGluZ19hcmVhLmphY2NhcmQuY2Nbc3VydmV5X3VuaXQgJWluJSBhbGxfc3VydmV5c1sxOjIwXSAmIHllYXIgPiAxOTc5XSkgKwogIGxhYnMoeCA9ICJSZWxhdGl2ZSBmaXNoaW5nIGNhdGNoIiwgIHkgPSAizrItZGl2ZXJzaXR5IikgKwogIGdlb21fcG9pbnQoYWVzKHggPSBzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZywgeSA9IGFubnVhbF9kaXNzaW1pbGFyaXR5X3ZhbHVlKSwgYWxwaGEgPSAwLjMpICsKICBnZW9tX3Ntb290aChhZXMoeCA9IHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnLCB5ID0gYW5udWFsX2Rpc3NpbWlsYXJpdHlfdmFsdWUpLCBtZXRob2QgPSAibG0iKSArCiAgZmFjZXRfd3JhcCh+U3VydmV5X05hbWVfU2Vhc29uLCBzY2FsZXM9ICJmcmVlIiwgbmNvbCA9IDQpICsKICB0aGVtZV9jbGFzc2ljKCkpCgpnZ3NhdmUocHJlZHNfc2J0X21lYW5fZmlzaGluZ19zdXJ2ZXlfZmFjZXRfMV8yMCwgcGF0aCA9IGhlcmU6OmhlcmUoImZpZ3VyZXMiKSwgZmlsZW5hbWUgPSAicHJlZHNfc2J0X21lYW5fZmlzaGluZ19zdXJ2ZXlfZmFjZXRfMV8yMC5qcGciLCBoZWlnaHQgPSAxMiwgd2lkdGggPTkpCgoocHJlZHNfc2J0X21lYW5fZmlzaGluZ19zdXJ2ZXlfZmFjZXRfMjFfMzQgPC0gZ2dwbG90KGRhdGEgPSBkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX2FyZWEuamFjY2FyZC5jY1tzdXJ2ZXlfdW5pdCAlaW4lIGFsbF9zdXJ2ZXlzW2MoMjE6MzQpXSAmIHllYXIgPiAxOTc5XSkgKwogIGxhYnMoeCA9ICJSZWxhdGl2ZSBmaXNoaW5nIGNhdGNoIiwgIHkgPSAizrItZGl2ZXJzaXR5IikgKwogIGdlb21fcG9pbnQoYWVzKHggPSBzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZywgeSA9IGFubnVhbF9kaXNzaW1pbGFyaXR5X3ZhbHVlKSwgYWxwaGEgPSAwLjMpICsKICBnZW9tX3Ntb290aChhZXMoeCA9IHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnLCB5ID0gYW5udWFsX2Rpc3NpbWlsYXJpdHlfdmFsdWUpLCBtZXRob2QgPSAibG0iKSArCiAgZmFjZXRfd3JhcCh+U3VydmV5X05hbWVfU2Vhc29uLCBzY2FsZXM9ICJmcmVlIiwgbmNvbCA9IDQpICsKICB0aGVtZV9jbGFzc2ljKCkpCgpnZ3NhdmUocHJlZHNfc2J0X21lYW5fZmlzaGluZ19zdXJ2ZXlfZmFjZXRfMjFfMzQsIHBhdGggPSBoZXJlOjpoZXJlKCJmaWd1cmVzIiksIGZpbGVuYW1lID0gInByZWRzX3NidF9tZWFuX2Zpc2hpbmdfc3VydmV5X2ZhY2V0XzIxXzM0LmpwZyIsIGhlaWdodCA9IDEyLCB3aWR0aCA9OSkKCgpgYGAKCiMjI1Bsb3QgbnVtYmVyIG9mIHRvd3MgcGVyIHllYXIgcGVyIHJlZ2lvbgpgYGB7cn0KdG93c195ZWFyIDwtIHVuaXF1ZShkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX2FyZWEuamFjY2FyZFssLihzdXJ2ZXlfdW5pdCwgaGF1bF9pZF9jb3VudF9hbm51YWwsIGFyZWFfa20sIHllYXIsIFN1cnZleV9OYW1lX1NlYXNvbildKQoKbWluX2hhdWxfZGVuc2l0eSA8LSBtaW4odG93c195ZWFyJGhhdWxfaWRfY291bnRfYW5udWFsL3Rvd3NfeWVhciRhcmVhX2ttKQptYXhfaGF1bF9kZW5zaXR5IDwtIG1heCh0b3dzX3llYXIkaGF1bF9pZF9jb3VudF9hbm51YWwvdG93c195ZWFyJGFyZWFfa20pCgoodG93X2RlbnNpdHlfc3VydmV5X2ZhY2V0XzFfMjAgPC0gZ2dwbG90KGRhdGEgPSB0b3dzX3llYXJbc3VydmV5X3VuaXQgJWluJSBhbGxfc3VydmV5c1sxOjIwXV0pICsKICBsYWJzKHggPSAiWWVhciIsICB5ID0gZXhwcmVzc2lvbigiVG93IGRlbnNpdHkgKHRvd3MgcGVyIGttIl4yKiIpIikpICsKICBnZW9tX3BvaW50KGFlcyh4ID0geWVhciwgeSA9IGhhdWxfaWRfY291bnRfYW5udWFsL2FyZWFfa20pKSArCiAgeWxpbShjKG1pbl9oYXVsX2RlbnNpdHktMC4wMDAxLCBtYXhfaGF1bF9kZW5zaXR5KzAuMDAwMSkpICsKICBmYWNldF93cmFwKH5TdXJ2ZXlfTmFtZV9TZWFzb24sIG5jb2wgPSA0KSArCiAgdGhlbWVfY2xhc3NpYygpKQoKZ2dzYXZlKHRvd19kZW5zaXR5X3N1cnZleV9mYWNldF8xXzIwLCBwYXRoID0gaGVyZTo6aGVyZSgiZmlndXJlcyIpLCBmaWxlbmFtZSA9ICJ0b3dfZGVuc2l0eV9zdXJ2ZXlfZmFjZXRfMV8yMC5qcGciLCBoZWlnaHQgPSAxMiwgd2lkdGggPTkpCgoodG93X2RlbnNpdHlfc3VydmV5X2ZhY2V0XzIxXzM0IDwtIGdncGxvdChkYXRhID0gdG93c195ZWFyW3N1cnZleV91bml0ICVpbiUgYWxsX3N1cnZleXNbMjE6MzRdXSkgKwogIGxhYnMoeCA9ICJZZWFyIiwgIHkgPSBleHByZXNzaW9uKCJUb3cgZGVuc2l0eSAodG93cyBwZXIga20iXjIqIikiKSkgKwogIGdlb21fcG9pbnQoYWVzKHggPSB5ZWFyLCB5ID0gaGF1bF9pZF9jb3VudF9hbm51YWwvYXJlYV9rbSkpICsKICB5bGltKGMobWluX2hhdWxfZGVuc2l0eS0wLjAwMDEsIG1heF9oYXVsX2RlbnNpdHkrMC4wMDAxKSkgKwogIGZhY2V0X3dyYXAoflN1cnZleV9OYW1lX1NlYXNvbiwgbmNvbCA9IDQpICsKICB0aGVtZV9jbGFzc2ljKCkpCgpnZ3NhdmUodG93X2RlbnNpdHlfc3VydmV5X2ZhY2V0XzIxXzM0LCBwYXRoID0gaGVyZTo6aGVyZSgiZmlndXJlcyIpLCBmaWxlbmFtZSA9ICJ0b3dfZGVuc2l0eV9zdXJ2ZXlfZmFjZXRfMjFfMzQuanBnIiwgaGVpZ2h0ID0gMTIsIHdpZHRoID05KQoKI21pbmltdW0gYW5kIG1heGltdW0gZGlzc2ltaWxhcml0eSB2YWx1ZQptaW5fZGlzc2ltaWxhcml0eSA8LSBtaW4oZGlzc2ltaWxhcml0aWVzX3RlbXBfZmlzaGluZ19hcmVhLmphY2NhcmQkYW5udWFsX2Rpc3NpbWlsYXJpdHlfdmFsdWUpCm1heF9kaXNzaW1pbGFyaXR5IDwtIG1heChkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX2FyZWEuamFjY2FyZCRhbm51YWxfZGlzc2ltaWxhcml0eV92YWx1ZSkKCiNob3cgZG9lcyB0b3cgZGVuc2l0eSB2YXJ5IHdpdGggZGlzc2ltaWxhcml0eT8KdG93X2RlbnNpdHlfZGlzc2ltaWxhcml0eV8xXzIwIDwtIAogIGdncGxvdChkYXRhID0gZGlzc2ltaWxhcml0aWVzX3RlbXBfZmlzaGluZ19hcmVhLmphY2NhcmRbZGlzc2ltaWxhcml0eV9tZXRyaWMgPT0gImphY2NhcmRfZGlzc2ltaWxhcml0eV9pbmRleF9iaW5hcnkiICYgc3VydmV5X3VuaXQgJWluJSBhbGxfc3VydmV5c1sxOjIwXV0pICsKICBnZW9tX3BvaW50KGFlcyh4ID0gKGhhdWxfaWRfY291bnRfYW5udWFsL2FyZWFfa20pLCB5ID0gYW5udWFsX2Rpc3NpbWlsYXJpdHlfdmFsdWUsIGNvbG9yID0geWVhciksIHNpemUgPSAyKSArCiAgdmlyaWRpczo6c2NhbGVfY29sb3JfdmlyaWRpcygpICsKICBmYWNldF93cmFwKH5TdXJ2ZXlfTmFtZV9TZWFzb24sIG5jb2wgPSA0LCBzY2FsZXMgPSAiZnJlZSIpICsKICBsYWJzKHggPSBleHByZXNzaW9uKCJUb3cgZGVuc2l0eSAodG93cyBwZXIga20iXjIqIikiKSwgeSA9ICLOsi1kaXZlcnNpdHkiLCBjb2xvciA9ICJZZWFyIikgKwogICAjIHhsaW0oYyhtaW5faGF1bF9kZW5zaXR5LTAuMDAwMSwgbWF4X2hhdWxfZGVuc2l0eSswLjAwMDEpKSArCiAgICMgeWxpbShjKG1pbl9kaXNzaW1pbGFyaXR5LTAuMDEsbWF4X2Rpc3NpbWlsYXJpdHkrMC4wMSkpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHZqdXN0ID0gMC41LCBoanVzdCA9IDEpKQoKZ2dzYXZlKHRvd19kZW5zaXR5X2Rpc3NpbWlsYXJpdHlfMV8yMCwgcGF0aCA9IGhlcmU6OmhlcmUoImZpZ3VyZXMiKSwgZmlsZW5hbWUgPSAidG93X2RlbnNpdHlfZGlzc2ltaWxhcml0eV8xXzIwLmpwZyIsIGhlaWdodCA9IDEyLCB3aWR0aCA9OSkKCnRvd19kZW5zaXR5X2Rpc3NpbWlsYXJpdHlfMjFfMzQgPC0gCiAgZ2dwbG90KGRhdGEgPSBkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX2FyZWEuamFjY2FyZFtkaXNzaW1pbGFyaXR5X21ldHJpYyA9PSAiamFjY2FyZF9kaXNzaW1pbGFyaXR5X2luZGV4X2JpbmFyeSIgJiBzdXJ2ZXlfdW5pdCAlaW4lIGFsbF9zdXJ2ZXlzWzIxOjM0XV0pICsKICBnZW9tX3BvaW50KGFlcyh4ID0gKGhhdWxfaWRfY291bnRfYW5udWFsL2FyZWFfa20pLCB5ID0gYW5udWFsX2Rpc3NpbWlsYXJpdHlfdmFsdWUsIGNvbG9yID0geWVhciksIHNpemUgPSAyKSArCiAgdmlyaWRpczo6c2NhbGVfY29sb3JfdmlyaWRpcygpICsKICBmYWNldF93cmFwKH5TdXJ2ZXlfTmFtZV9TZWFzb24sIG5jb2wgPSA0LCBzY2FsZXMgPSAiZnJlZSIpICsKICBsYWJzKHggPSBleHByZXNzaW9uKCJUb3cgZGVuc2l0eSAodG93cyBwZXIga20iXjIqIikiKSwgeSA9ICLOsi1kaXZlcnNpdHkiLCBjb2xvciA9ICJZZWFyIikgKwogICAjIHhsaW0oYyhtaW5faGF1bF9kZW5zaXR5LTAuMDAwMSwgbWF4X2hhdWxfZGVuc2l0eSswLjAwMDEpKSArCiAgICMgeWxpbShjKG1pbl9kaXNzaW1pbGFyaXR5LTAuMDEsbWF4X2Rpc3NpbWlsYXJpdHkrMC4wMSkpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHZqdXN0ID0gMC41LCBoanVzdCA9IDEpKQoKZ2dzYXZlKHRvd19kZW5zaXR5X2Rpc3NpbWlsYXJpdHlfMjFfMzQsIHBhdGggPSBoZXJlOjpoZXJlKCJmaWd1cmVzIiksIGZpbGVuYW1lID0gInRvd19kZW5zaXR5X2Rpc3NpbWlsYXJpdHlfMjFfMzQuanBnIiwgaGVpZ2h0ID0gMTIsIHdpZHRoID05KQoKCiNQbG90IGFsbCBhdCBvbmNlPwp0b3dfZGVuc2l0eV9kaXNzaW1pbGFyaXR5IDwtIAogIGdncGxvdChkYXRhID0gZGlzc2ltaWxhcml0aWVzX3RlbXBfZmlzaGluZ19hcmVhLmphY2NhcmRbZGlzc2ltaWxhcml0eV9tZXRyaWMgPT0gImphY2NhcmRfZGlzc2ltaWxhcml0eV9pbmRleF9iaW5hcnkiXSkgKwogIGdlb21fcG9pbnQoYWVzKHggPSAoaGF1bF9pZF9jb3VudF9hbm51YWwvYXJlYV9rbSksIHkgPSBhbm51YWxfZGlzc2ltaWxhcml0eV92YWx1ZSwgY29sb3IgPSBTdXJ2ZXlfTmFtZV9TZWFzb24pLCBzaXplID0gMikgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xvcl9saW5rJGhleCkgKwogIGxhYnMoeCA9IGV4cHJlc3Npb24oIlRvdyBkZW5zaXR5ICh0b3dzIHBlciBrbSJeMioiKSIpLCB5ID0gIs6yLWRpdmVyc2l0eSIsIGNvbG9yID0gIlllYXIiKSArCiAgICMgeGxpbShjKG1pbl9oYXVsX2RlbnNpdHktMC4wMDAxLCBtYXhfaGF1bF9kZW5zaXR5KzAuMDAwMSkpICsKICAgIyB5bGltKGMobWluX2Rpc3NpbWlsYXJpdHktMC4wMSxtYXhfZGlzc2ltaWxhcml0eSswLjAxKSkgKwogIHRoZW1lX2NsYXNzaWMoKQoKI2FuZCBieSBudW1iZXJzPwpyZXN1bHQgPC0gZGlzc2ltaWxhcml0aWVzX3RlbXBfZmlzaGluZ19hcmVhLmphY2NhcmRbLCAuKG1heF9kZW5zaXR5ID0gbWF4KGhhdWxfaWRfY291bnRfYW5udWFsL2FyZWFfa20sIG5hLnJtID0gVFJVRSksIAogICAgICAgICAgICAgICAgIG1pbl9kZW5zaXR5ID0gbWluKGhhdWxfaWRfY291bnRfYW5udWFsL2FyZWFfa20sIG5hLnJtID0gVFJVRSkpLCAKICAgICAgICAgICAgIGJ5ID0gU3VydmV5X05hbWVfU2Vhc29uXQoKcmVzdWx0WyxyYW5nZTo9IG1heF9kZW5zaXR5LW1pbl9kZW5zaXR5XQoKZ2dwbG90KGRhdGEgPSByZXN1bHQpICsKICBnZW9tX3BvaW50KGFlcyh4ID0gU3VydmV5X05hbWVfU2Vhc29uLCB5ID0gcmFuZ2UpKSArCiAgdGhlbWVfY2xhc3NpYygpICsKICBsYWJzKHggPSAiIix5ID0gIlJhbmdlIG9mIHRvdyBkZW5zaXR5IHZhbHVlcyBpbiB0b3cva21eMiIpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdD0xKSkKCmBgYAoKRGlzc2ltaWxhcml0eSBieSBzZWFzb24gb2Ygc2FtcGxpbmcKYGBge3J9CmRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfYXJlYS5qYWNjYXJkWyxzZWFzb24gOj0gZmFjdG9yKHNlYXNvbiwgbGV2ZWxzID0gYygiU3ByaW5nIiwiU3VtbWVyIiwiRmFsbCIsIldpbnRlciIpKV0KCmdncGxvdChkaXNzaW1pbGFyaXRpZXNfdGVtcF9maXNoaW5nX2FyZWEuamFjY2FyZCkgKwogIGdlb21fYm94cGxvdChhZXMoeCA9IHNlYXNvbiwgeSA9IGFubnVhbF9kaXNzaW1pbGFyaXR5X3ZhbHVlKSkgKwogIHRoZW1lX2NsYXNzaWMoKQpgYGAKCgoKIyMjU2V0IHVwIGRyZWRnZSB0byBpZGVudGlmeSBiZXN0IHBlcmZvcm1pbmcgbW9kZWxzCmBgYHtyfQoKb3B0aW9ucyhuYS5hY3Rpb24gPSAibmEuZmFpbCIpCgpkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0IDwtIGRpc3NpbWlsYXJpdGllc190ZW1wX2Zpc2hpbmdfYXJlYS5qYWNjYXJkWywuCiAgICAgICAgICAgICAgICAgICh5ZWFyLCBzdXJ2ZXlfdW5pdCwKICAgICAgICAgICAgICAgICAgICB5ZWFybHlfbWVhbl9ieXBvaW50X2F2ZywgeWVhcmx5X21heF9ieXBvaW50X2F2ZywgeWVhcmx5X21pbl9ieXBvaW50X2F2Zyx5ZWFybHlfc2Vhc19ieXBvaW50X2F2ZywKICAgICAgICAgICAgICAgICAgICB5ZWFybHlfbWVhbl9ieXBvaW50X1NELCB5ZWFybHlfbWF4X2J5cG9pbnRfU0QsIHllYXJseV9taW5fYnlwb2ludF9TRCx5ZWFybHlfc2Vhc19ieXBvaW50X1NELAogICAgICAgICAgICAgICAgICAgIHllYXJseV9tZWFuX2J5cG9pbnRfYXZnLnMsIHllYXJseV9tYXhfYnlwb2ludF9hdmcucywgeWVhcmx5X21pbl9ieXBvaW50X2F2Zy5zLHllYXJseV9zZWFzX2J5cG9pbnRfYXZnLnMsCiAgICAgICAgICAgICAgICAgICAgYW5udWFsX2Rpc3NpbWlsYXJpdHlfdmFsdWUsCiAgICAgICAgICAgICAgICAgICAgaGF1bF9pZF9jb3VudF9hbm51YWwsCiAgICAgICAgICAgICAgICAgICAgc3BwX2NvdW50X2FubnVhbCwgZGVwdGhfYW5udWFsX2F2ZywKICAgICAgICAgICAgICAgICAgICBkZXB0aF9hbm51YWxfcmFuZ2UsIGxhdGl0dWRlX2FubnVhbF9hdmcsCiAgICAgICAgICAgICAgICAgICAgbGF0aXR1ZGVfYW5udWFsX3JhbmdlLCBhcmVhX2ttLCBzZWFzb24sIHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnKV0KCiNtZXJnZSBpbiB3aXRoIGNvbG9ycyBmb3IgcGxvdHRpbmcgcHJlZGljdGlvbnMgYnkgc3VydmV5CmRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHQgPC0gY29sb3JfbGlua1tkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0LCBvbiA9ICJzdXJ2ZXlfdW5pdCJdCgojSWYgTkEgZm9yIGFueSBjb3ZhcmlhdGUsIGRlbGV0ZSByb3cKI1ZpZXcoZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdCkKI0RlbGV0ZWQ6CiAgI0JlZm9yZSAxOTgwIGFuZCBhZnRlciAyMDE5CiAgI0d1bGYgb2YgU2FpbnQgTGF1cmVuY2UgU291dGggKG5vIGRlcHRoIGRhdGEpCiAgI05vIGNsZWFyIFNBVSBtYXRjaCBmb3IgUm9ja2FsbCBQbGF0ZWF1CmRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHQgPC0gZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdFtjb21wbGV0ZS5jYXNlcyhkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0KV0KCgpkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0WywgeWVhcmx5X21lYW5fYnlwb2ludF9hdmcuc2NhbGVkYWNyb3NzYWxsIDo9IHNjYWxlKHllYXJseV9tZWFuX2J5cG9pbnRfYXZnKV1bLCB5ZWFybHlfbWVhbl9ieXBvaW50X1NELnNjYWxlZGFjcm9zc2FsbCA6PSBzY2FsZSh5ZWFybHlfbWVhbl9ieXBvaW50X1NEKV1bLCB5ZWFybHlfbWluX2J5cG9pbnRfYXZnLnNjYWxlZGFjcm9zc2FsbCA6PSBzY2FsZSh5ZWFybHlfbWluX2J5cG9pbnRfYXZnKV1bLCB5ZWFybHlfbWF4X2J5cG9pbnRfYXZnLnNjYWxlZGFjcm9zc2FsbCA6PSBzY2FsZSh5ZWFybHlfbWF4X2J5cG9pbnRfYXZnKV1bLCB5ZWFybHlfc2Vhc19ieXBvaW50X2F2Zy5zY2FsZWRhY3Jvc3NhbGwgOj0gc2NhbGUoeWVhcmx5X3NlYXNfYnlwb2ludF9hdmcpXVssaGF1bF9pZF9jb3VudF9hbm51YWwuc2NhbGVkYWNyb3NzYWxsIDo9IHNjYWxlKGhhdWxfaWRfY291bnRfYW5udWFsKV1bLHNwcF9jb3VudF9hbm51YWwuc2NhbGVkYWNyb3NzYWxsIDo9IHNjYWxlKHNwcF9jb3VudF9hbm51YWwpXVssZGVwdGhfYW5udWFsX2F2Zy5zY2FsZWRhY3Jvc3NhbGwgOj0gc2NhbGUoZGVwdGhfYW5udWFsX2F2ZyldWyxkZXB0aF9hbm51YWxfcmFuZ2Uuc2NhbGVkYWNyb3NzYWxsIDo9IHNjYWxlKGRlcHRoX2FubnVhbF9yYW5nZSldIFssbGF0aXR1ZGVfYW5udWFsX2F2Zy5zY2FsZWRhY3Jvc3NhbGwgOj0gc2NhbGUobGF0aXR1ZGVfYW5udWFsX2F2ZyldWyxsYXRpdHVkZV9hbm51YWxfcmFuZ2Uuc2NhbGVkYWNyb3NzYWxsIDo9IHNjYWxlKGxhdGl0dWRlX2FubnVhbF9yYW5nZSldWyxhcmVhX2ttLnNjYWxlZGFjcm9zc2FsbCA6PSBzY2FsZShhcmVhX2ttKV0KCgpgYGAKCiMjI0Z1bGwgbW9kZWwKfiB0ZW1wICsgc3VydmV5X3VuaXQgKyBmaXNoaW5nICsgYXJlYSArIGxhdGl0dWRlIHJhbmdlICsgbGF0aXR1ZGUgYXZlcmFnZSArIGRlcHRoIHJhbmdlICsgZGVwdGggYXZlcmFnZSArIHNwcCBjb3VudCArICMgb2YgaGF1bHMgKyBzZWFzb24gKyBBUiBmb3IgeWVhcgoKRm9yIHRlbXBlcmF0dXJlLCB3ZSB3aWxsIGxvb2sgYXQ6Ci1tZWFuIChzY2FsZWQgYWNyb3NzIGFsbCByZWdpb25zKQotbWF4ICAoc2NhbGVkIGFjcm9zcyBhbGwgcmVnaW9ucykKLW1pbiAoc2NhbGVkIGFjcm9zcyBhbGwgcmVnaW9ucykKLXNlYXMgIChzY2FsZWQgYWNyb3NzIGFsbCByZWdpb25zKQotU0QKCkNvbXBhcmluZyB0ZW1wIHZhcmlhYmxlcyBBTkQgdGhlIHByZXNlbmNlL2Fic2VuY2UgcmFuZG9tIGVmZmVjdCBmb3IgeWVhcgpgYGB7ciBmaXQgZ2xvYmFsIG1vZH0KCmdsb2JhbF9tb2RfbWVhbl90ZW1wX2xtZXJfc3VydmV5eWVhciA8LSBsbWVyKGFubnVhbF9kaXNzaW1pbGFyaXR5X3ZhbHVlIH4gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VydmV5X3VuaXQ6eWVhcmx5X21lYW5fYnlwb2ludF9hdmcuc2NhbGVkYWNyb3NzYWxsICsgI3RlbXAgYW5kIHN1cnZleSB1bml0IChwb3NzaWJsZSBpbnRlcmFjdGlvbikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXJ2ZXlfdW5pdDpzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZyArICNmaXNoaW5nIGVmZm9ydCBhbmQgc3VydmV5IHVuaXQgKHBvc3NpYmxlIGludGVyYWN0aW9uKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZWFfa20uc2NhbGVkYWNyb3NzYWxsICsgI2FyZWEKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXRpdHVkZV9hbm51YWxfcmFuZ2Uuc2NhbGVkYWNyb3NzYWxsICsgI2xhdGl0dWRlIHJhbmdlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGF0aXR1ZGVfYW5udWFsX2F2Zy5zY2FsZWRhY3Jvc3NhbGwgKyAjbGF0aXR1ZGUgYXZnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwdGhfYW5udWFsX3JhbmdlLnNjYWxlZGFjcm9zc2FsbCArICNkZXB0aCByYW5nZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcHRoX2FubnVhbF9hdmcuc2NhbGVkYWNyb3NzYWxsICsgI2RlcHRoIGF2ZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwcF9jb3VudF9hbm51YWwuc2NhbGVkYWNyb3NzYWxsICsgI3NwcCAjCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGF1bF9pZF9jb3VudF9hbm51YWwuc2NhbGVkYWNyb3NzYWxsICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWFzb24gKyB5ZWFybHlfbWVhbl9ieXBvaW50X2F2Zy5zY2FsZWRhY3Jvc3NhbGwgKyBzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZyArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMXxzdXJ2ZXlfdW5pdCkgKyAoMXx5ZWFyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdCkKCmdsb2JhbF9tb2RfbWVhbl90ZW1wX2xtZXJfc3VydmV5IDwtIGxtZXIoYW5udWFsX2Rpc3NpbWlsYXJpdHlfdmFsdWUgfiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXJ2ZXlfdW5pdDp5ZWFybHlfbWVhbl9ieXBvaW50X2F2Zy5zY2FsZWRhY3Jvc3NhbGwgKyAjdGVtcCBhbmQgc3VydmV5IHVuaXQgKHBvc3NpYmxlIGludGVyYWN0aW9uKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cnZleV91bml0OnN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnICsgI2Zpc2hpbmcgZWZmb3J0IGFuZCBzdXJ2ZXkgdW5pdCAocG9zc2libGUgaW50ZXJhY3Rpb24pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJlYV9rbS5zY2FsZWRhY3Jvc3NhbGwgKyAjYXJlYQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhdGl0dWRlX2FubnVhbF9yYW5nZS5zY2FsZWRhY3Jvc3NhbGwgKyAjbGF0aXR1ZGUgcmFuZ2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXRpdHVkZV9hbm51YWxfYXZnLnNjYWxlZGFjcm9zc2FsbCArICNsYXRpdHVkZSBhdmcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXB0aF9hbm51YWxfcmFuZ2Uuc2NhbGVkYWNyb3NzYWxsICsgI2RlcHRoIHJhbmdlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwdGhfYW5udWFsX2F2Zy5zY2FsZWRhY3Jvc3NhbGwgKyAjZGVwdGggYXZnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BwX2NvdW50X2FubnVhbC5zY2FsZWRhY3Jvc3NhbGwgKyAjc3BwICMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYXVsX2lkX2NvdW50X2FubnVhbC5zY2FsZWRhY3Jvc3NhbGwgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlYXNvbiArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZWFybHlfbWVhbl9ieXBvaW50X2F2Zy5zY2FsZWRhY3Jvc3NhbGwgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWcgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKDF8c3VydmV5X3VuaXQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0KQoKZ2xvYmFsX21vZF9tYXhfdGVtcF9sbWVyX3N1cnZleXllYXIgPC0gbG1lcihhbm51YWxfZGlzc2ltaWxhcml0eV92YWx1ZSB+IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cnZleV91bml0OnllYXJseV9tYXhfYnlwb2ludF9hdmcuc2NhbGVkYWNyb3NzYWxsICsgI3RlbXAgYW5kIHN1cnZleSB1bml0IChwb3NzaWJsZSBpbnRlcmFjdGlvbikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXJ2ZXlfdW5pdDpzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZyArICNmaXNoaW5nIGVmZm9ydCBhbmQgc3VydmV5IHVuaXQgKHBvc3NpYmxlIGludGVyYWN0aW9uKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZWFfa20uc2NhbGVkYWNyb3NzYWxsICsgI2FyZWEKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXRpdHVkZV9hbm51YWxfcmFuZ2Uuc2NhbGVkYWNyb3NzYWxsICsgI2xhdGl0dWRlIHJhbmdlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGF0aXR1ZGVfYW5udWFsX2F2Zy5zY2FsZWRhY3Jvc3NhbGwgKyAjbGF0aXR1ZGUgYXZnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwdGhfYW5udWFsX3JhbmdlLnNjYWxlZGFjcm9zc2FsbCArICNkZXB0aCByYW5nZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcHRoX2FubnVhbF9hdmcuc2NhbGVkYWNyb3NzYWxsICsgI2RlcHRoIGF2ZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwcF9jb3VudF9hbm51YWwuc2NhbGVkYWNyb3NzYWxsICsgI3NwcCAjCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGF1bF9pZF9jb3VudF9hbm51YWwuc2NhbGVkYWNyb3NzYWxsICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWFzb24gKyB5ZWFybHlfbWVhbl9ieXBvaW50X2F2Zy5zY2FsZWRhY3Jvc3NhbGwgKyBzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZyArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMXxzdXJ2ZXlfdW5pdCkgKyAoMXx5ZWFyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdCkKCmdsb2JhbF9tb2RfbWF4X3RlbXBfbG1lcl9zdXJ2ZXkgPC0gbG1lcihhbm51YWxfZGlzc2ltaWxhcml0eV92YWx1ZSB+IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cnZleV91bml0OnllYXJseV9tYXhfYnlwb2ludF9hdmcuc2NhbGVkYWNyb3NzYWxsICsgI3RlbXAgYW5kIHN1cnZleSB1bml0IChwb3NzaWJsZSBpbnRlcmFjdGlvbikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXJ2ZXlfdW5pdDpzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZyArICNmaXNoaW5nIGVmZm9ydCBhbmQgc3VydmV5IHVuaXQgKHBvc3NpYmxlIGludGVyYWN0aW9uKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyZWFfa20uc2NhbGVkYWNyb3NzYWxsICsgI2FyZWEKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXRpdHVkZV9hbm51YWxfcmFuZ2Uuc2NhbGVkYWNyb3NzYWxsICsgI2xhdGl0dWRlIHJhbmdlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGF0aXR1ZGVfYW5udWFsX2F2Zy5zY2FsZWRhY3Jvc3NhbGwgKyAjbGF0aXR1ZGUgYXZnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwdGhfYW5udWFsX3JhbmdlLnNjYWxlZGFjcm9zc2FsbCArICNkZXB0aCByYW5nZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcHRoX2FubnVhbF9hdmcuc2NhbGVkYWNyb3NzYWxsICsgI2RlcHRoIGF2ZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwcF9jb3VudF9hbm51YWwuc2NhbGVkYWNyb3NzYWxsICsgI3NwcCAjCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGF1bF9pZF9jb3VudF9hbm51YWwuc2NhbGVkYWNyb3NzYWxsICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWFzb24gKyB5ZWFybHlfbWVhbl9ieXBvaW50X2F2Zy5zY2FsZWRhY3Jvc3NhbGwgKyBzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZyArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMXxzdXJ2ZXlfdW5pdCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHQpCgpnbG9iYWxfbW9kX21pbl90ZW1wX2xtZXJfc3VydmV5eWVhciA8LSBsbWVyKGFubnVhbF9kaXNzaW1pbGFyaXR5X3ZhbHVlIH4gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VydmV5X3VuaXQ6eWVhcmx5X21pbl9ieXBvaW50X2F2Zy5zY2FsZWRhY3Jvc3NhbGwgKyAjdGVtcCBhbmQgc3VydmV5IHVuaXQgKHBvc3NpYmxlIGludGVyYWN0aW9uKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cnZleV91bml0OnN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnICsgI2Zpc2hpbmcgZWZmb3J0IGFuZCBzdXJ2ZXkgdW5pdCAocG9zc2libGUgaW50ZXJhY3Rpb24pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJlYV9rbS5zY2FsZWRhY3Jvc3NhbGwgKyAjYXJlYQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhdGl0dWRlX2FubnVhbF9yYW5nZS5zY2FsZWRhY3Jvc3NhbGwgKyAjbGF0aXR1ZGUgcmFuZ2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXRpdHVkZV9hbm51YWxfYXZnLnNjYWxlZGFjcm9zc2FsbCArICNsYXRpdHVkZSBhdmcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXB0aF9hbm51YWxfcmFuZ2Uuc2NhbGVkYWNyb3NzYWxsICsgI2RlcHRoIHJhbmdlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwdGhfYW5udWFsX2F2Zy5zY2FsZWRhY3Jvc3NhbGwgKyAjZGVwdGggYXZnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BwX2NvdW50X2FubnVhbC5zY2FsZWRhY3Jvc3NhbGwgKyAjc3BwICMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYXVsX2lkX2NvdW50X2FubnVhbC5zY2FsZWRhY3Jvc3NhbGwgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlYXNvbiArIHllYXJseV9tZWFuX2J5cG9pbnRfYXZnLnNjYWxlZGFjcm9zc2FsbCArIHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgxfHN1cnZleV91bml0KSArICgxfHllYXIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0KQoKZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdFssIHN1cnZleV91bml0IDo9IGZhY3RvcihzdXJ2ZXlfdW5pdCwgbGV2ZWxzID0gc29ydChhbGxfc3VydmV5cykpXQoKZ2xvYmFsX21vZF9taW5fdGVtcF9sbWVyX3N1cnZleSA8LWxtZXIoYW5udWFsX2Rpc3NpbWlsYXJpdHlfdmFsdWUgfiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXJ2ZXlfdW5pdDp5ZWFybHlfbWluX2J5cG9pbnRfYXZnLnNjYWxlZGFjcm9zc2FsbCArICN0ZW1wIGFuZCBzdXJ2ZXkgdW5pdCAocG9zc2libGUgaW50ZXJhY3Rpb24pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VydmV5X3VuaXQ6c3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWcgKyAjZmlzaGluZyBlZmZvcnQgYW5kIHN1cnZleSB1bml0IChwb3NzaWJsZSBpbnRlcmFjdGlvbikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmVhX2ttLnNjYWxlZGFjcm9zc2FsbCArICNhcmVhCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGF0aXR1ZGVfYW5udWFsX3JhbmdlLnNjYWxlZGFjcm9zc2FsbCArICNsYXRpdHVkZSByYW5nZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhdGl0dWRlX2FubnVhbF9hdmcuc2NhbGVkYWNyb3NzYWxsICsgI2xhdGl0dWRlIGF2ZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcHRoX2FubnVhbF9yYW5nZS5zY2FsZWRhY3Jvc3NhbGwgKyAjZGVwdGggcmFuZ2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXB0aF9hbm51YWxfYXZnLnNjYWxlZGFjcm9zc2FsbCArICNkZXB0aCBhdmcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcHBfY291bnRfYW5udWFsLnNjYWxlZGFjcm9zc2FsbCArICNzcHAgIwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhdWxfaWRfY291bnRfYW5udWFsLnNjYWxlZGFjcm9zc2FsbCArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vhc29uICsgeWVhcmx5X21lYW5fYnlwb2ludF9hdmcuc2NhbGVkYWNyb3NzYWxsICsgc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWcgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKDF8c3VydmV5X3VuaXQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0KQoKZ2xvYmFsX21vZF9zZWFzX3RlbXBfbG1lcl9zdXJ2ZXl5ZWFyIDwtIGxtZXIoYW5udWFsX2Rpc3NpbWlsYXJpdHlfdmFsdWUgfiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXJ2ZXlfdW5pdDp5ZWFybHlfc2Vhc19ieXBvaW50X2F2Zy5zY2FsZWRhY3Jvc3NhbGwgKyAjdGVtcCBhbmQgc3VydmV5IHVuaXQgKHBvc3NpYmxlIGludGVyYWN0aW9uKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cnZleV91bml0OnN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnICsgI2Zpc2hpbmcgZWZmb3J0IGFuZCBzdXJ2ZXkgdW5pdCAocG9zc2libGUgaW50ZXJhY3Rpb24pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJlYV9rbS5zY2FsZWRhY3Jvc3NhbGwgKyAjYXJlYQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhdGl0dWRlX2FubnVhbF9yYW5nZS5zY2FsZWRhY3Jvc3NhbGwgKyAjbGF0aXR1ZGUgcmFuZ2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXRpdHVkZV9hbm51YWxfYXZnLnNjYWxlZGFjcm9zc2FsbCArICNsYXRpdHVkZSBhdmcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXB0aF9hbm51YWxfcmFuZ2Uuc2NhbGVkYWNyb3NzYWxsICsgI2RlcHRoIHJhbmdlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwdGhfYW5udWFsX2F2Zy5zY2FsZWRhY3Jvc3NhbGwgKyAjZGVwdGggYXZnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BwX2NvdW50X2FubnVhbC5zY2FsZWRhY3Jvc3NhbGwgKyAjc3BwICMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYXVsX2lkX2NvdW50X2FubnVhbC5zY2FsZWRhY3Jvc3NhbGwgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlYXNvbiArIHllYXJseV9tZWFuX2J5cG9pbnRfYXZnLnNjYWxlZGFjcm9zc2FsbCArIHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgxfHN1cnZleV91bml0KSArICgxfHllYXIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0KQoKZ2xvYmFsX21vZF9zZWFzX3RlbXBfbG1lcl9zdXJ2ZXkgPC0gbG1lcihhbm51YWxfZGlzc2ltaWxhcml0eV92YWx1ZSB+IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cnZleV91bml0OnllYXJseV9zZWFzX2J5cG9pbnRfYXZnLnNjYWxlZGFjcm9zc2FsbCArICN0ZW1wIGFuZCBzdXJ2ZXkgdW5pdCAocG9zc2libGUgaW50ZXJhY3Rpb24pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VydmV5X3VuaXQ6c3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWcgKyAjZmlzaGluZyBlZmZvcnQgYW5kIHN1cnZleSB1bml0IChwb3NzaWJsZSBpbnRlcmFjdGlvbikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmVhX2ttLnNjYWxlZGFjcm9zc2FsbCArICNhcmVhCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGF0aXR1ZGVfYW5udWFsX3JhbmdlLnNjYWxlZGFjcm9zc2FsbCArICNsYXRpdHVkZSByYW5nZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhdGl0dWRlX2FubnVhbF9hdmcuc2NhbGVkYWNyb3NzYWxsICsgI2xhdGl0dWRlIGF2ZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcHRoX2FubnVhbF9yYW5nZS5zY2FsZWRhY3Jvc3NhbGwgKyAjZGVwdGggcmFuZ2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXB0aF9hbm51YWxfYXZnLnNjYWxlZGFjcm9zc2FsbCArICNkZXB0aCBhdmcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcHBfY291bnRfYW5udWFsLnNjYWxlZGFjcm9zc2FsbCArICNzcHAgIwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhdWxfaWRfY291bnRfYW5udWFsLnNjYWxlZGFjcm9zc2FsbCArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vhc29uICsgeWVhcmx5X21lYW5fYnlwb2ludF9hdmcuc2NhbGVkYWNyb3NzYWxsICsgc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWcgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKDF8c3VydmV5X3VuaXQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0KQoKZ2xvYmFsX21vZF9TRF90ZW1wX2xtZXJfc3VydmV5eWVhciA8LSBsbWVyKGFubnVhbF9kaXNzaW1pbGFyaXR5X3ZhbHVlIH4gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VydmV5X3VuaXQ6eWVhcmx5X21lYW5fYnlwb2ludF9TRC5zY2FsZWRhY3Jvc3NhbGwgKyAjdGVtcCBhbmQgc3VydmV5IHVuaXQgKHBvc3NpYmxlIGludGVyYWN0aW9uKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cnZleV91bml0OnN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnICsgI2Zpc2hpbmcgZWZmb3J0IGFuZCBzdXJ2ZXkgdW5pdCAocG9zc2libGUgaW50ZXJhY3Rpb24pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJlYV9rbS5zY2FsZWRhY3Jvc3NhbGwgKyAjYXJlYQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhdGl0dWRlX2FubnVhbF9yYW5nZS5zY2FsZWRhY3Jvc3NhbGwgKyAjbGF0aXR1ZGUgcmFuZ2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXRpdHVkZV9hbm51YWxfYXZnLnNjYWxlZGFjcm9zc2FsbCArICNsYXRpdHVkZSBhdmcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXB0aF9hbm51YWxfcmFuZ2Uuc2NhbGVkYWNyb3NzYWxsICsgI2RlcHRoIHJhbmdlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwdGhfYW5udWFsX2F2Zy5zY2FsZWRhY3Jvc3NhbGwgKyAjZGVwdGggYXZnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BwX2NvdW50X2FubnVhbC5zY2FsZWRhY3Jvc3NhbGwgKyAjc3BwICMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYXVsX2lkX2NvdW50X2FubnVhbC5zY2FsZWRhY3Jvc3NhbGwgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlYXNvbiArIHllYXJseV9tZWFuX2J5cG9pbnRfYXZnLnNjYWxlZGFjcm9zc2FsbCArIHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgxfHN1cnZleV91bml0KSArICgxfHllYXIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0KQoKZ2xvYmFsX21vZF9TRF90ZW1wX2xtZXJfc3VydmV5IDwtIGxtZXIoYW5udWFsX2Rpc3NpbWlsYXJpdHlfdmFsdWUgfiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdXJ2ZXlfdW5pdDp5ZWFybHlfbWVhbl9ieXBvaW50X1NELnNjYWxlZGFjcm9zc2FsbCArICN0ZW1wIGFuZCBzdXJ2ZXkgdW5pdCAocG9zc2libGUgaW50ZXJhY3Rpb24pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3VydmV5X3VuaXQ6c3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWcgKyAjZmlzaGluZyBlZmZvcnQgYW5kIHN1cnZleSB1bml0IChwb3NzaWJsZSBpbnRlcmFjdGlvbikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmVhX2ttLnNjYWxlZGFjcm9zc2FsbCArICNhcmVhCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGF0aXR1ZGVfYW5udWFsX3JhbmdlLnNjYWxlZGFjcm9zc2FsbCArICNsYXRpdHVkZSByYW5nZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhdGl0dWRlX2FubnVhbF9hdmcuc2NhbGVkYWNyb3NzYWxsICsgI2xhdGl0dWRlIGF2ZwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlcHRoX2FubnVhbF9yYW5nZS5zY2FsZWRhY3Jvc3NhbGwgKyAjZGVwdGggcmFuZ2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZXB0aF9hbm51YWxfYXZnLnNjYWxlZGFjcm9zc2FsbCArICNkZXB0aCBhdmcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcHBfY291bnRfYW5udWFsLnNjYWxlZGFjcm9zc2FsbCArICNzcHAgIwogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhdWxfaWRfY291bnRfYW5udWFsLnNjYWxlZGFjcm9zc2FsbCArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vhc29uICsgeWVhcmx5X21lYW5fYnlwb2ludF9hdmcuc2NhbGVkYWNyb3NzYWxsICsgc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWcgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKDF8c3VydmV5X3VuaXQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0KQoKVmlldyhBSUNjKGdsb2JhbF9tb2RfbWVhbl90ZW1wX2xtZXJfc3VydmV5LCBnbG9iYWxfbW9kX21heF90ZW1wX2xtZXJfc3VydmV5LCBnbG9iYWxfbW9kX21pbl90ZW1wX2xtZXJfc3VydmV5LCBnbG9iYWxfbW9kX3NlYXNfdGVtcF9sbWVyX3N1cnZleSwgZ2xvYmFsX21vZF9TRF90ZW1wX2xtZXJfc3VydmV5LAogICAgICAgICAgZ2xvYmFsX21vZF9tZWFuX3RlbXBfbG1lcl9zdXJ2ZXl5ZWFyLCBnbG9iYWxfbW9kX21heF90ZW1wX2xtZXJfc3VydmV5eWVhciwgZ2xvYmFsX21vZF9taW5fdGVtcF9sbWVyX3N1cnZleXllYXIsIGdsb2JhbF9tb2Rfc2Vhc190ZW1wX2xtZXJfc3VydmV5eWVhciwgZ2xvYmFsX21vZF9TRF90ZW1wX2xtZXJfc3VydmV5eWVhcikpCgojYnVpbGQgZGF0YSB0YWJsZSB0byByZXBvcnQgQUlDYwpnbG9iYWxfbW9kX3RlbXBfdGFibGUgPC0gZGF0YS50YWJsZSgKICBgUmFuZG9tIGVmZmVjdCB5ZWFyYCA9IGMoCiAgICBjKHJlcChGLDUpLHJlcChULDUpKQogICksCiAgYFRlbXBlcmF0dXJlIHZhcmlhYmxlYCA9IHJlcChjKCAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICJBdmVyYWdlIG1lYW4gU0JUIiwKICAgICAgICAgICAgICAiQXZlcmFnZSBtYXhpbXVtIFNCVCIsICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgIkF2ZXJhZ2UgbWluaW11bSBTQlQiLCAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICJBdmVyYWdlIFNCVCBzZWFzb25hbGl0eSIsICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAiU0JUIFNEIiksMiksCiAgZGVsdGFBSUNjID0gc2lnbmlmKG1pbihBSUNjKGdsb2JhbF9tb2RfbWVhbl90ZW1wX2xtZXJfc3VydmV5LCBnbG9iYWxfbW9kX21heF90ZW1wX2xtZXJfc3VydmV5LCBnbG9iYWxfbW9kX21pbl90ZW1wX2xtZXJfc3VydmV5LCBnbG9iYWxfbW9kX3NlYXNfdGVtcF9sbWVyX3N1cnZleSwgZ2xvYmFsX21vZF9TRF90ZW1wX2xtZXJfc3VydmV5LAogICAgICAgICAgZ2xvYmFsX21vZF9tZWFuX3RlbXBfbG1lcl9zdXJ2ZXl5ZWFyLCBnbG9iYWxfbW9kX21heF90ZW1wX2xtZXJfc3VydmV5eWVhciwgZ2xvYmFsX21vZF9taW5fdGVtcF9sbWVyX3N1cnZleXllYXIsIGdsb2JhbF9tb2Rfc2Vhc190ZW1wX2xtZXJfc3VydmV5eWVhciwgZ2xvYmFsX21vZF9TRF90ZW1wX2xtZXJfc3VydmV5eWVhcilbLDJdKS1BSUNjKGdsb2JhbF9tb2RfbWVhbl90ZW1wX2xtZXJfc3VydmV5LCBnbG9iYWxfbW9kX21heF90ZW1wX2xtZXJfc3VydmV5LCBnbG9iYWxfbW9kX21pbl90ZW1wX2xtZXJfc3VydmV5LCBnbG9iYWxfbW9kX3NlYXNfdGVtcF9sbWVyX3N1cnZleSwgZ2xvYmFsX21vZF9TRF90ZW1wX2xtZXJfc3VydmV5LAogICAgICAgICAgZ2xvYmFsX21vZF9tZWFuX3RlbXBfbG1lcl9zdXJ2ZXl5ZWFyLCBnbG9iYWxfbW9kX21heF90ZW1wX2xtZXJfc3VydmV5eWVhciwgZ2xvYmFsX21vZF9taW5fdGVtcF9sbWVyX3N1cnZleXllYXIsIGdsb2JhbF9tb2Rfc2Vhc190ZW1wX2xtZXJfc3VydmV5eWVhciwgZ2xvYmFsX21vZF9TRF90ZW1wX2xtZXJfc3VydmV5eWVhcilbLDJdLDIpKQoKI29yZGVyIGJ5IGFpY2MKc2V0b3JkZXIoZ2xvYmFsX21vZF90ZW1wX3RhYmxlLGNvbHMgPSAtImRlbHRhQUlDYyIpCgpnbG9iYWxfbW9kX3RlbXBfdGFibGVbLFJhbmsgOj0gc2VxKDEsMTAsYnkgPSAxKV0KCmdsb2JhbF9tb2Rfc2J0X3RhYmxlIDwtIGdsb2JhbF9tb2RfdGVtcF90YWJsZVssLihSYW5rLGBSYW5kb20gZWZmZWN0IHllYXJgLGBUZW1wZXJhdHVyZSB2YXJpYWJsZWAsIGRlbHRhQUlDYyldCgpmd3JpdGUoZ2xvYmFsX21vZF9zYnRfdGFibGUsIGhlcmU6OmhlcmUoIm91dHB1dCIsImdsb2JhbF9tb2Rfc2J0X3RhYmxlLmNzdiIpKQoKYGBgCgpCZXN0IHBlcmZvcm1pbmcgZ2xvYmFsIG1vZGVsIGluY2x1ZGVzIG1pbmltdW0gdGVtcGVyYXR1cmUgKGNlbnRlcmVkIGFuZCBzY2FsZWQpIChTdGlsbCB0aGUgY2FzZSBhcyBvZiBPY3RvYmVyIDQsIDIwMjQpCgpOb3csIGxvb2sgYXQgZGlmZmVyZW50IGNvbWJpbmF0aW9ucyBvZiBhbGwgcHJlZGljdG9ycyAobWluIHRlbXApIHVzaW5nIGRyZWRnZQoKR2xvYmFsIG1vZGVsOiBnbG9iYWxfbW9kX21pbl90ZW1wCgpgYGB7cn0Kb3B0aW9ucyhuYS5hY3Rpb24gPSAibmEuZmFpbCIpICMgIHByZXZlbnQgZml0dGluZyBzdWItbW9kZWxzIHRvIGRpZmZlcmVudCBkYXRhc2V0cwpkZCA8LSBkcmVkZ2UoZ2xvYmFsX21vZF9tZWFuX3RlbXBfbG1lcl9zdXJ2ZXkpCmRkLmR0IDwtIGRhdGEudGFibGUoZGQpClZpZXcoZGQpCgojb25seSBtb2RlbHMgbGVzcyB0aGFuIDQgZGVsdGEgQUlDYyAoMiBtb2RlbHMpCmRkLmR0LjIgPC0gZGQuZHRbZGVsdGEgPD0gMixdCgpjb2xuYW1lcyhkZC5kdC4yKQoKI2luIHRoaXMgc3RlcCwgd2UgZGVsZXRlIGNvZWZmaWNpZW50IHZhbHVlcyBiZWNhdXNlIHdlIHdpbGwgcHVsbCB0aGVtIGJhY2sgaW4gbGF0ZXIgd2hlbiB3ZSBjYWxjdWxhdGUgYm90aCBTRSBhbmQgY29lZmZpY2llbnRzIChvdGhlciB0aGFuIGludGVyYWN0aW9uLCB3aGljaCB3ZSBrZWVwIGhlcmUpCmRkLmR0LjIuZm9ybWF0dGVkIDwtIGRkLmR0LjJbLFJhbmsgOj0gYXMubnVtZXJpYyhyb3duYW1lcyhkZC5kdC4yKSldWywuKFJhbmssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnOnN1cnZleV91bml0YCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgc3VydmV5X3VuaXQ6eWVhcmx5X21lYW5fYnlwb2ludF9hdmcuc2NhbGVkYWNyb3NzYWxsYCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWx0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3ZWlnaHQsc2Vhc29uCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKV0KCiNhZGQgci1zcXVhcmVkIHZhbHVlcwojIEl0ZXJhdGUgdGhyb3VnaCB0aGUgYmVzdCBtb2RlbHMgYW5kIGV4dHJhY3QgUi1zcXVhcmVkIHZhbHVlcwpyX3NxdWFyZWRfY29uZGl0aW9uYWxfdmFsdWVzIDwtbGlzdCgpCnJfc3F1YXJlZF9tYXJnaW5hbF92YWx1ZXMgPC1saXN0KCkKZm9yIChpIGluIDE6bnJvdyhkZC5kdC4yLmZvcm1hdHRlZCkpIHsKICByX3NxdWFyZWRfbWFyZ2luYWwgPC0gci5zcXVhcmVkR0xNTShnZXQubW9kZWxzKGRkLCBzdWJzZXQgPSBpKVtbMV1dKVsxXQogIHJfc3F1YXJlZF9jb25kaXRpb25hbCA8LSByLnNxdWFyZWRHTE1NKGdldC5tb2RlbHMoZGQsIHN1YnNldCA9IGkpW1sxXV0pWzJdCiAgcl9zcXVhcmVkX2NvbmRpdGlvbmFsX3ZhbHVlcyA8LSB1bmxpc3QoYyhyX3NxdWFyZWRfY29uZGl0aW9uYWxfdmFsdWVzLHJfc3F1YXJlZF9jb25kaXRpb25hbCkpCiAgcl9zcXVhcmVkX21hcmdpbmFsX3ZhbHVlcyA8LSB1bmxpc3QoYyhyX3NxdWFyZWRfbWFyZ2luYWxfdmFsdWVzLHJfc3F1YXJlZF9tYXJnaW5hbCkpCn0KCmRkLmR0LjIuZm9ybWF0dGVkWywiUiBzcXVhcmVkIG1hcmdpbmFsIiA6PSByX3NxdWFyZWRfbWFyZ2luYWxfdmFsdWVzXQpkZC5kdC4yLmZvcm1hdHRlZFssIlIgc3F1YXJlZCBjb25kaXRpb25hbCIgOj0gcl9zcXVhcmVkX2NvbmRpdGlvbmFsX3ZhbHVlc10KCiNlbXB0eSBkYXRhIHRhYmxlCgptb2RlbF9jb2VmX3NlX2ZpbGwgPC0gZGF0YS50YWJsZShSYW5rID0gYXMubnVtZXJpYygpLCBjb2VmX25hbWUgPSBhcy5jaGFyYWN0ZXIoKSxjb2VmID0gYXMubnVtZXJpYygpLCBzZSA9IGFzLm51bWVyaWMoKSkKCmZvciAoaSBpbiAxOm5yb3coZGQuZHQuMi5mb3JtYXR0ZWQpKXsKICBtb2RlbF9jb2VmX3NlX3NpbmdsZSA8LSBkYXRhLnRhYmxlKHVubGlzdChjb2VmVGFibGUoZGQsZnVsbCA9IFQpW1tpXV0pKQogIG1vZGVsX2NvZWZfc2Vfc2luZ2xlWyxjb2VmX25hbWVzIDo9IHJvd25hbWVzKHVubGlzdChjb2VmVGFibGUoZGQsZnVsbCA9IFQpW1tpXV0pKV0KICBtb2RlbF9jb2VmX3NlX3NpbmdsZVssUmFuayA6PSBpXQogIAogIGNvbG5hbWVzKG1vZGVsX2NvZWZfc2Vfc2luZ2xlKSA8LSBjKCJjb2VmIiwic2UiLCJkZiIsImNvZWZfbmFtZSIsIlJhbmsiKQogIAogICNyZWR1Y2UgdG8gY29sdW1ucyB3ZSBuZWVkCiAgbW9kZWxfY29lZl9zZV9zaW5nbGUgPC0gbW9kZWxfY29lZl9zZV9zaW5nbGVbLC4oUmFuaywgY29lZl9uYW1lLCBjb2VmLCBzZSldCiAgCiAgbW9kZWxfY29lZl9zZV9maWxsIDwtIHJiaW5kKG1vZGVsX2NvZWZfc2VfZmlsbCxtb2RlbF9jb2VmX3NlX3NpbmdsZSkKfQoKI2Zvcm1hdCB0byBtZXJnZSB3aXRoIG1vZGVsIHJhbmtpbmdzIGFuZCBhdmVyYWdlZCBtb2RlbAptb2RlbF9jb2VmX3NlX2ZpbGxbLGNvZWZfc2UgOj0gcGFzdGUwKHJvdW5kKGNvZWYsMyksIiDCsSAiLHJvdW5kKHNlLDMpKV0KCiNkZWxldGUgZXh0cmEgY29sdW1ucwptb2RlbF9jb2VmX3NlX2ZpbGwgPC0gbW9kZWxfY29lZl9zZV9maWxsWywuKFJhbmssY29lZl9uYW1lLGNvZWZfc2UpXQoKI2xvbmcgdG8gd2lkZQptb2RlbF9jb2VmX3NlX2ZpbGwudyA8LSBkY2FzdChtb2RlbF9jb2VmX3NlX2ZpbGwsIGZvcm11bGEgPSBSYW5rIH4gY29lZl9uYW1lLCB2YWx1ZS52YXIgPSBjKCJjb2VmX3NlIikpCgojbWVyZ2UgbW9kZWxfY29lZl9zZV9maWxsIHdpdGggZGQuZHQuMi5mb3JtYXR0ZWQKbW9kZWxfY29lZl9zZV9BSUMgPC0gZGQuZHQuMi5mb3JtYXR0ZWRbbW9kZWxfY29lZl9zZV9maWxsLncsIG9uID0gIlJhbmsiXQoKI21vZGVsIGF2ZXJhZ2UgYWxsIG1vZGVscyB3aXRoIGRlbHRhIDwgNCAoOCBtb2RlbHMpCm1vZGVsX2F2Z19kZWx0YTQgPC1tb2RlbC5hdmcoZGQsIHN1YnNldCA9IGRlbHRhIDwgNCwgZml0ID0gVCkgI05COiBUaGUg4oCYc3Vic2V04oCZIChvciDigJhjb25kaXRpb25hbOKAmSkgYXZlcmFnZSBvbmx5ICAgYXZlcmFnZXMgb3ZlciB0aGUgbW9kZWxzIHdoZXJlIHRoZSBwYXJhbWV0ZXIgYXBwZWFycy4gQW4gYWx0ZXJuYXRpdmUsIHRoZSDigJhmdWxs4oCZIGF2ZXJhZ2UgYXNzdW1lcyB0aGF0IGEgdmFyaWFibGUgaXMgaW5jbHVkZWQgaW4gZXZlcnkgbW9kZWwsIGJ1dCBpbiBzb21lIG1vZGVscyB0aGUgY29ycmVzcG9uZGluZyBjb2VmZmljaWVudCAoYW5kIGl0cyByZXNwZWN0aXZlIHZhcmlhbmNlKSBpcyBzZXQgdG8gemVyby4gVW5saWtlIHRoZSDigJhzdWJzZXQgYXZlcmFnZeKAmSwgaXQgZG9lcyBub3QgaGF2ZSBhIHRlbmRlbmN5IG9mIGJpYXNpbmcgdGhlIHZhbHVlIGF3YXkgZnJvbSB6ZXJvLiBUaGUg4oCYZnVsbOKAmSBhdmVyYWdlIGlzIGEgdHlwZSBvZiBzaHJpbmthZ2UgZXN0aW1hdG9yLCBhbmQgZm9yIHZhcmlhYmxlcyB3aXRoIGEgd2VhayByZWxhdGlvbnNoaXAgdG8gdGhlIHJlc3BvbnNlIGl0IGlzIHNtYWxsZXIgdGhhbiDigJhzdWJzZXTigJkgZXN0aW1hdG9ycy4sIGZpdCA9IFQgZml0cyB0aGUgY29tcG9uZW50IG1vZGVscyBhZ2FpbgoKbW9kZWxfYXZnX3ZhbHVlcyA8LSBhcy5kYXRhLnRhYmxlKGNvZWZUYWJsZShtb2RlbF9hdmdfZGVsdGE0LGZpbGwgPSBUKSkgIyB3aXRoIFNFCmNvZWZfbmFtZXMgPC0gbmFtZXMoY29lZihtb2RlbC5hdmcoZGQsIHN1YnNldCA9IGRlbHRhIDwgNCkpKQptb2RlbF9hdmdfdmFsdWVzWyxjb2VmX25hbWU6PWNvZWZfbmFtZXNdWyxjb2VmOj1Fc3RpbWF0ZV1bLEVzdGltYXRlOj1OVUxMXVssZGY6PU5VTExdWyxzZTo9IGBTdGQuIEVycm9yYF1bLGBTdGQuIEVycm9yYCA6PSBOVUxMXQoKI25ldyBjb2x1bW4gd2l0aCBjb2VmIGFuZCBTRQptb2RlbF9hdmdfdmFsdWVzWyxjb2VmX3NlIDo9IHBhc3RlMChyb3VuZChjb2VmLDMpLCIgwrEgIixyb3VuZChzZSwzKSldCgojbG9uZyB0byB3aWRlIGZvciBtb2RlbCBhdmcKbW9kZWxfYXZnLndpZGUgPC0gZGNhc3QobW9kZWxfYXZnX3ZhbHVlcywgZm9ybXVsYSA9IC4gfiBjb2VmX25hbWUsIHZhbHVlLnZhciA9IGMoImNvZWZfc2UiKSkKCiNhZGQgcmFuayBvZiAibW9kZWwgYXZnIiB0byB0YWJsZQptb2RlbF9hdmcud2lkZVssUmFuayA6PSAiTW9kZWwgYXZnIl0KCmJlc3RfbW9kZWxfc2J0X2phY2NhcmRfdGFibGVfZm9ybWF0dGVkIDwtIHJiaW5kKG1vZGVsX2NvZWZfc2VfQUlDLCBtb2RlbF9hdmcud2lkZSwgZmlsbCA9IFQpCgojZ2V0IHJpZCBvZiBpbnRlcmFjdGlvbiBjb2VmZmljaWVudHMKYmVzdF9tb2RlbF9zYnRfamFjY2FyZF90YWJsZV9mb3JtYXR0ZWQuciA8LSBiZXN0X21vZGVsX3NidF9qYWNjYXJkX3RhYmxlX2Zvcm1hdHRlZFssLihSYW5rLGAoSW50ZXJjZXB0KWAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJlYV9rbS5zY2FsZWRhY3Jvc3NhbGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwdGhfYW5udWFsX2F2Zy5zY2FsZWRhY3Jvc3NhbGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVwdGhfYW5udWFsX3JhbmdlLnNjYWxlZGFjcm9zc2FsbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYXVsX2lkX2NvdW50X2FubnVhbC5zY2FsZWRhY3Jvc3NhbGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGF0aXR1ZGVfYW5udWFsX2F2Zy5zY2FsZWRhY3Jvc3NhbGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGF0aXR1ZGVfYW5udWFsX3JhbmdlLnNjYWxlZGFjcm9zc2FsbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcHBfY291bnRfYW5udWFsLnNjYWxlZGFjcm9zc2FsbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWFzb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVhcmx5X21pbl9ieXBvaW50X2F2Zy5zY2FsZWRhY3Jvc3NhbGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnOnN1cnZleV91bml0YCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBgc3VydmV5X3VuaXQ6eWVhcmx5X21pbl9ieXBvaW50X2F2Zy5zY2FsZWRhY3Jvc3NhbGxgLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBSIHNxdWFyZWQgY29uZGl0aW9uYWxgLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBSIHNxdWFyZWQgbWFyZ2luYWxgLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbHRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdlaWdodAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICldCgojcm91bmQgdG8gMiBzaWduaWZpY2FudCBmaWd1cmVzCgojbmFtZXMgb2YgbnVtZXJpYyBjb2x1bW5zCm51bWVyaWNfY29scyA8LSBuYW1lcyhiZXN0X21vZGVsX3NidF9qYWNjYXJkX3RhYmxlX2Zvcm1hdHRlZC5yKVtzYXBwbHkoYmVzdF9tb2RlbF9zYnRfamFjY2FyZF90YWJsZV9mb3JtYXR0ZWQuciwgaXMubnVtZXJpYyldCgojIEFwcGx5IHNpZ25pZigpIG9ubHkgdG8gbnVtZXJpYyBjb2x1bW5zCmJlc3RfbW9kZWxfc2J0X2phY2NhcmRfdGFibGVfZm9ybWF0dGVkLnJbLCAobnVtZXJpY19jb2xzKSA6PSBsYXBwbHkoLlNELCBmdW5jdGlvbih4KSBpZiAoaXMubnVtZXJpYyh4KSkgc2lnbmlmKHgsIGRpZ2l0cyA9IDIpIGVsc2UgeCksIC5TRGNvbHMgPSBudW1lcmljX2NvbHNdCgojY2hhbmdlIGNvbHVtbiBuYW1lcywgaW4gY2FwdGlvbiBub3RlIHRoYXQgYWxsIHZhcmlhYmxlcyBhcmUgY2VudGVyZWQgYW5kIHNjYWxlZApjb2xuYW1lcyhiZXN0X21vZGVsX3NidF9qYWNjYXJkX3RhYmxlX2Zvcm1hdHRlZC5yKSA8LSBjKAoiUmFuayIsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAoiSW50ZXJjZXB0IiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiJBcmVhIiwgICAgICAgI3NjYWxlZCBhY3Jvc3MgYWxsICAgICAgICAgICAgICAgICAgICAKIkF2ZXJhZ2UgZGVwdGgiLCAgICAgICAgICAgICAgICAgIAoiRGVwdGggcmFuZ2UiLCAgICAgICAgICAgICAgICAKIk51bWJlciBvZiB0b3dzIiwgICAgIAoiQXZlcmFnZSBsYXRpdHVkZSIsICAgICAgICAgICAgICAgCiJMYXRpdHVkZSByYW5nZSIsICAgICAgICAgICAgIAoiU3BlY2llcyBjb3VudCIsICAgICAgICAgICAgICAgICAgCiJSZWxhdGl2ZSBjYXRjaCIsICNzY2FsZWQgd2l0aGluIHJlZ2lvbiAgICAKIlNlYXNvbiIsCiJTdXJ2ZXkiLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAoiQXZlcmFnZSBtaW5pbXVtIHRlbXBlcmF0dXJlIiwgICAgICAgICAgICAKIlN1cnZleSAqIHJlbGF0aXZlIGNhdGNoIiwgICAgICAgICAgICAKIlN1cnZleSAqIGF2ZyBtaW4gdGVtcGVyYXR1cmUiLAoiUiBzcXVhcmVkIiwKcGFzdGUwKCJcdTAzOTQiLCIgQUlDYyIpLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIApwYXN0ZTAoIlx1MDNDOSIpKQoKCgojc2F2ZSBhcyBjc3YKCmZ3cml0ZShiZXN0X21vZGVsX3NidF9qYWNjYXJkX3RhYmxlX2Zvcm1hdHRlZC5yLGhlcmU6OmhlcmUoIm91dHB1dCIsImJlc3RfbW9kZWxfc2J0X2phY2NhcmRfdGFibGVfZm9ybWF0dGVkLmNzdiIpKQpgYGAKCgoKUHJlZGljdCBkaXNzaW1pbGFyaXR5IGFjcm9zcyB5ZWFycyB1c2luZyBhdmVyYWdlZCBtb2RlbCAobW9kZWxfYXZnX2RlbHRhNCkKYGBge3J9CmRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHRfcHJlZGljdGlvbnMgPC0gY29weShkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0KQoKICAjYWxsb3dpbmcgdGVtcCBhbmQgZmlzaGluZyB0byB2YXJ5IChha2Egbm8gY2hhbmdlcykKICBkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0X3ByZWRpY3Rpb25zWyxwcmVkX2Rpc3NpbSA6PSBwcmVkaWN0KG1vZGVsX2F2Z19kZWx0YTQsIHNlLmZpdCA9IFQsIGZ1bGwgPSBGKVtbMV1dXVsscHJlZF9zZSA6PSBwcmVkaWN0KG1vZGVsX2F2Z19kZWx0YTQsIHNlLmZpdCA9IFQsIGZ1bGwgPSBGKVtbMl1dXSAjZnVsbCBhbGxvd3MgdXMgdG8gc3dpdGNoIGJhY2sgdG8gbWl4ZWQgZWZmZWN0IG1vZGVscwogIAogIAogIAogICNjb25zdGFudCB0ZW1wIGluIHJlZ2lvbnMgKGFrYSB0YWtlIG1lYW4gb2YgdGVtcGVyYXR1cmUgdmFsdWVzIHdpdGhpbiBzdXJ2ZXkgdW5pdHMgc28gdGhleSBhcmUgdGhlIHNhbWUgdmFsdWUgd2l0aGluIGVhY2ggeWVhciBmb3IgYSBzdXJ2ZXkpCiAgZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdF9wcmVkaWN0aW9uc19jb25zaXN0ZW50dGVtcGlucmVnIDwtIGNvcHkoZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdCkKICBkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0X3ByZWRpY3Rpb25zX2NvbnNpc3RlbnR0ZW1waW5yZWdbLHllYXJseV9taW5fYnlwb2ludF9hdmcuc2NhbGVkYWNyb3NzYWxsOj1tZWFuKHllYXJseV9taW5fYnlwb2ludF9hdmcuc2NhbGVkYWNyb3NzYWxsKSwuKHN1cnZleV91bml0KV0KCiAgI2NvbnN0YW50IGZpc2hpbmcgaW4gcmVnaW9ucyAoYWthIHRha2UgbWVhbiBvZiBmaXNoaW5nIHZhbHVlcyB3aXRoaW4gc3VydmV5IHVuaXRzIHNvIHRoZXkgYXJlIHRoZSBzYW1lIHZhbHVlIHdpdGhpbiBlYWNoIHllYXIgZm9yIGEgc3VydmV5KQogIGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHRfcHJlZGljdGlvbnNfY29uc2lzdGVudGZpc2hpbmdpbnJlZyA8LSBjb3B5KGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHQpCiAgZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdF9wcmVkaWN0aW9uc19jb25zaXN0ZW50ZmlzaGluZ2lucmVnWyxzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZzo9bWVhbihzdW1tZWRfdG9ubmVzX3NjYWxlZF9ieXJlZyksLihzdXJ2ZXlfdW5pdCldCgojYW5kIHRoZW4gd2l0aCBjb25zaXN0ZW50IHRlbXAgYW5kIGZpc2hpbmcgaW4gcmVnaW9ucyAoYWthIHRha2UgbWVhbiBvZiBib3RoIG1pbiB0ZW1wIGFuZCBmaXNoaW5nKQpkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0X3ByZWRpY3Rpb25zX2NvbnNpc3RlbnR0ZW1wZmlzaGluZ2lucmVnIDwtIGNvcHkoZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdCkKZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdF9wcmVkaWN0aW9uc19jb25zaXN0ZW50dGVtcGZpc2hpbmdpbnJlZ1ssc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWc6PW1lYW4oc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWcpLC4oc3VydmV5X3VuaXQpXVsseWVhcmx5X21pbl9ieXBvaW50X2F2Zy5zY2FsZWRhY3Jvc3NhbGw6PW1lYW4oeWVhcmx5X21pbl9ieXBvaW50X2F2Zy5zY2FsZWRhY3Jvc3NhbGwpLC4oc3VydmV5X3VuaXQpXQoKCiNhbGxvd2luZyB0ZW1wIGFuZCBmaXNoaW5nIHRvIHZhcnkgd2l0aGluIHJlZ3MgKG5vcm1hbCkKICAgIGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHRfcHJlZGljdGlvbnNbLHByZWRfZGlzc2ltIDo9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWRpY3QobW9kZWxfYXZnX2RlbHRhNCwgc2UuZml0ID0gVCwgZnVsbCA9IEYsIG5ld2RhdGEgPSAgIGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHRfcHJlZGljdGlvbnMpW1sxXV1dWyxwcmVkX3NlIDo9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZGljdChtb2RlbF9hdmdfZGVsdGE0LCBzZS5maXQgPSBULCBmdWxsID0gRiwgbmV3ZGF0YSA9ICAgZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdF9wcmVkaWN0aW9ucylbWzJdXV0KICAKI2FsbG93aW5nIG9ubHkgZmlzaGluZyB0byB2YXJ5IHdpdGhpbiByZWdpb25zICh3aXRoIG1lYW4gdGVtcCkKICAKICAgZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdF9wcmVkaWN0aW9uc19jb25zaXN0ZW50dGVtcGlucmVnWyxwcmVkX2Rpc3NpbSA6PSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZGljdChtb2RlbF9hdmdfZGVsdGE0LCBzZS5maXQgPSBULCBmdWxsID0gRiwgbmV3ZGF0YSA9IGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHRfcHJlZGljdGlvbnNfY29uc2lzdGVudHRlbXBpbnJlZylbWzFdXV1bLHByZWRfc2UgOj0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVkaWN0KG1vZGVsX2F2Z19kZWx0YTQsIHNlLmZpdCA9IFQsIGZ1bGwgPSBGLCBuZXdkYXRhID0gZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdF9wcmVkaWN0aW9uc19jb25zaXN0ZW50dGVtcGlucmVnKVtbMl1dXQoKICAKICAKI2FsbG93aW5nIG9ubHkgdGVtcGVyYXR1cmUgdG8gdmFyeSB3aXRoaW4gcmVnaW9ucyAod2l0aCBtZWFuIGZpc2hpbmcgcHJlc3N1cmUpCiAgICAgCiAgIGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHRfcHJlZGljdGlvbnNfY29uc2lzdGVudGZpc2hpbmdpbnJlZ1sscHJlZF9kaXNzaW0gOj0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZGljdChtb2RlbF9hdmdfZGVsdGE0LCBzZS5maXQgPSBULCBmdWxsID0gRiwgbmV3ZGF0YSA9IGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHRfcHJlZGljdGlvbnNfY29uc2lzdGVudGZpc2hpbmdpbnJlZylbWzFdXV1bLHByZWRfc2UgOj0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVkaWN0KG1vZGVsX2F2Z19kZWx0YTQsIHNlLmZpdCA9IFQsIGZ1bGwgPSBGLCBuZXdkYXRhID0gZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdF9wcmVkaWN0aW9uc19jb25zaXN0ZW50ZmlzaGluZ2lucmVnKVtbMl1dXQogICAKI2FuZCB0aGVuIHdpdGggY29uc2lzdGVudCB0ZW1wIGFuZCBmaXNoaW5nIGFjcm9zcyByZWdpb25zIChtZWFuIG9mIGJvdGggZmlzaGluZyBhbmQgdGVtcCkKZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdF9wcmVkaWN0aW9uc19jb25zaXN0ZW50dGVtcGZpc2hpbmdpbnJlZyA8LSBjb3B5KGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHQpCmRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHRfcHJlZGljdGlvbnNfY29uc2lzdGVudHRlbXBmaXNoaW5naW5yZWdbLHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnOj1tZWFuKHN1bW1lZF90b25uZXNfc2NhbGVkX2J5cmVnKSwuKHN1cnZleV91bml0KV1bLHllYXJseV9taW5fYnlwb2ludF9hdmcuc2NhbGVkYWNyb3NzYWxsOj1tZWFuKHllYXJseV9taW5fYnlwb2ludF9hdmcuc2NhbGVkYWNyb3NzYWxsKSwuKHN1cnZleV91bml0KV0KCmRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHRfcHJlZGljdGlvbnNfY29uc2lzdGVudHRlbXBmaXNoaW5naW5yZWdbLHByZWRfZGlzc2ltIDo9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZGljdChtb2RlbF9hdmdfZGVsdGE0LCBzZS5maXQgPSBULCBmdWxsID0gRiwgbmV3ZGF0YSA9IGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHRfcHJlZGljdGlvbnNfY29uc2lzdGVudHRlbXBmaXNoaW5naW5yZWcpW1sxXV1dWyxwcmVkX3NlIDo9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZGljdChtb2RlbF9hdmdfZGVsdGE0LCBzZS5maXQgPSBULCBmdWxsID0gRiwgbmV3ZGF0YSA9IGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHRfcHJlZGljdGlvbnNfY29uc2lzdGVudHRlbXBmaXNoaW5naW5yZWcpW1syXV1dCgoKI2FuZCB0aGVuIHdpdGggY29uc2lzdGVudCB0ZW1wIGFuZCBmaXNoaW5nIGFjcm9zcyByZWdpb25zIChtZWFuIG9mIGJvdGggZmlzaGluZyBhbmQgdGVtcCkKZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdF9wcmVkaWN0aW9uc19jb25zaXN0ZW50dGVtcGZpc2hpbmcgPC0gY29weShkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0KQpkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0X3ByZWRpY3Rpb25zX2NvbnNpc3RlbnR0ZW1wZmlzaGluZ1ssc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWc6PW1lYW4oc3VtbWVkX3Rvbm5lc19zY2FsZWRfYnlyZWcpXVsseWVhcmx5X21pbl9ieXBvaW50X2F2Zy5zY2FsZWRhY3Jvc3NhbGw6PW1lYW4oeWVhcmx5X21pbl9ieXBvaW50X2F2Zy5zY2FsZWRhY3Jvc3NhbGwpXQoKZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdF9wcmVkaWN0aW9uc19jb25zaXN0ZW50dGVtcGZpc2hpbmdbLHByZWRfZGlzc2ltIDo9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZGljdChtb2RlbF9hdmdfZGVsdGE0LCBzZS5maXQgPSBULCBmdWxsID0gRiwgbmV3ZGF0YSA9IGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHRfcHJlZGljdGlvbnNfY29uc2lzdGVudHRlbXBmaXNoaW5nKVtbMV1dXVsscHJlZF9zZSA6PQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWRpY3QobW9kZWxfYXZnX2RlbHRhNCwgc2UuZml0ID0gVCwgZnVsbCA9IEYsIG5ld2RhdGEgPSBkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0X3ByZWRpY3Rpb25zX2NvbnNpc3RlbnR0ZW1wZmlzaGluZylbWzJdXV0KCiNGT1IgQ09MT1IgVE8gTUFUQ0gKI3NvcnQgY29sb3IgbGluayBieSBzdXJ2ZXkgbmFtZSBzZWFzb24KI2FscGhhYmV0aWNhbCBvcmRlcgpjb2xvcl9saW5rX2FscGhhIDwtIHNldG9yZGVyKGNvbG9yX2xpbmssIHN1cnZleV91bml0KQoKI2V4Y2x1ZGUgc3VydmV5cyB3ZSBkb24ndCBpbmNsdWRlCmNvbG9yX2xpbmtfYWxwaGEgPC0gY29sb3JfbGlua19hbHBoYVtzdXJ2ZXlfdW5pdCAlaW4lIHVuaXF1ZShkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0X3ByZWRpY3Rpb25zJHN1cnZleV91bml0KSxdCgpjb2xvcl9hbHBoYV9vcmRlciA8LSBjb2xvcl9saW5rX2FscGhhWyxoZXhdCmxhYmVsX2FscGhhX29yZGVyIDwtIGNvbG9yX2xpbmtfYWxwaGFbLFN1cnZleV9OYW1lX1NlYXNvbl0KICAKCiNtYWludGFpbiB0ZW1wIGFuZCBmaXNoaW5nCiNwbG90CnByZWRpY3RlZF92YWx1ZXNfdGVtcF9maXNoaW5nIDwtIGdncGxvdChkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0X3ByZWRpY3Rpb25zKSArCiAgZ2VvbV9wb2ludChhZXMoeCA9IHllYXIsIHkgPSBhbm51YWxfZGlzc2ltaWxhcml0eV92YWx1ZSwgY29sb3IgPSBzdXJ2ZXlfdW5pdCkpICsKICBnZW9tX2xpbmUoYWVzKHggPSB5ZWFyLCB5ID0gcHJlZF9kaXNzaW0sIGNvbG9yID0gc3VydmV5X3VuaXQpKSArCiAgZ2VvbV9yaWJib24oYWVzKHggPSB5ZWFyLCB5bWluID0gcHJlZF9kaXNzaW0tcHJlZF9zZSwgeW1heCA9IHByZWRfZGlzc2ltK3ByZWRfc2UsIGZpbGwgPSBzdXJ2ZXlfdW5pdCksIGFscGhhID0gMC4zKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbG9yX2FscGhhX29yZGVyLCBsYWJlbHMgPSBsYWJlbF9hbHBoYV9vcmRlciwgbmFtZSA9ICJTdXJ2ZXkiKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY29sb3JfYWxwaGFfb3JkZXIsIGxhYmVscyA9IGxhYmVsX2FscGhhX29yZGVyLCBuYW1lID0gIlN1cnZleSIpICsKICBsYWJzKHggPSAiWWVhciIseSA9ICJBdmVyYWdlIGFubnVhbCB0b3RhbFxuQnJheSBDdXJ0aXMgZGlzc2ltaWxhcml0eSIpICsKICB5bGltKDAsMS41KSArCiAgdGhlbWVfY2xhc3NpYygpICsKICBnZ3RpdGxlKCJBdmVyYWdlIG1vZGVsIHByZWRpY3Rpb25zIikKCiNhdmVyYWdlIHRlbXAgYW5kIGZpc2hpbmcgZm9yIGVhY2ggcmVnaW9uCnByZWRpY3RlZF92YWx1ZXNfdGVtcF9maXNoaW5nX21lYW50ZW1wZmlzaGluZ2luc3VydmV5IDwtIGdncGxvdChkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0X3ByZWRpY3Rpb25zX2NvbnNpc3RlbnR0ZW1wZmlzaGluZ2lucmVnKSArCiAgZ2VvbV9wb2ludChhZXMoeCA9IHllYXIsIHkgPSBhbm51YWxfZGlzc2ltaWxhcml0eV92YWx1ZSwgY29sb3IgPSBzdXJ2ZXlfdW5pdCkpICsKICBnZW9tX2xpbmUoYWVzKHggPSB5ZWFyLCB5ID0gcHJlZF9kaXNzaW0sIGNvbG9yID0gc3VydmV5X3VuaXQpKSArCiAgZ2VvbV9yaWJib24oYWVzKHggPSB5ZWFyLCB5bWluID0gcHJlZF9kaXNzaW0tcHJlZF9zZSwgeW1heCA9IHByZWRfZGlzc2ltK3ByZWRfc2UsIGZpbGwgPSBzdXJ2ZXlfdW5pdCksIGFscGhhID0gMC4zKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGNvbG9yX2FscGhhX29yZGVyLCBsYWJlbHMgPSBsYWJlbF9hbHBoYV9vcmRlciwgbmFtZSA9ICJTdXJ2ZXkiKSArCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gY29sb3JfYWxwaGFfb3JkZXIsIGxhYmVscyA9IGxhYmVsX2FscGhhX29yZGVyLCBuYW1lID0gIlN1cnZleSIpICsKICBsYWJzKHggPSAiWWVhciIseSA9ICJBdmVyYWdlIGFubnVhbCB0b3RhbFxuQnJheSBDdXJ0aXMgZGlzc2ltaWxhcml0eSIpICsKICB5bGltKDAsMS41KSArCiAgdGhlbWVfY2xhc3NpYygpICsKICBnZ3RpdGxlKCJBdmVyYWdlIG1vZGVsIHByZWRpY3Rpb25zIHdpdGggbWVhblxuc3VydmV5IHRlbXBlcmF0dXJlIGFuZCBmaXNoaW5nIHByZXNzdXJlIikKCiNhdmVyYWdlIHRlbXAgYW5kIGZpc2hpbmcgYWNyb3NzIGFsbCByZWdpb25zCnByZWRpY3RlZF92YWx1ZXNfdGVtcF9maXNoaW5nX21lYW50ZW1wZmlzaGluZyA8LSBnZ3Bsb3QoZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdF9wcmVkaWN0aW9uc19jb25zaXN0ZW50dGVtcGZpc2hpbmcpICsKICBnZW9tX3BvaW50KGFlcyh4ID0geWVhciwgeSA9IGFubnVhbF9kaXNzaW1pbGFyaXR5X3ZhbHVlLCBjb2xvciA9IHN1cnZleV91bml0KSkgKwogIGdlb21fbGluZShhZXMoeCA9IHllYXIsIHkgPSBwcmVkX2Rpc3NpbSwgY29sb3IgPSBzdXJ2ZXlfdW5pdCkpICsKICBnZW9tX3JpYmJvbihhZXMoeCA9IHllYXIsIHltaW4gPSBwcmVkX2Rpc3NpbS1wcmVkX3NlLCB5bWF4ID0gcHJlZF9kaXNzaW0rcHJlZF9zZSwgZmlsbCA9IHN1cnZleV91bml0KSwgYWxwaGEgPSAwLjEpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gY29sb3JfYWxwaGFfb3JkZXIsIGxhYmVscyA9IGxhYmVsX2FscGhhX29yZGVyLCBuYW1lID0gIlN1cnZleSIpICsKICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjb2xvcl9hbHBoYV9vcmRlciwgbGFiZWxzID0gbGFiZWxfYWxwaGFfb3JkZXIsIG5hbWUgPSAiU3VydmV5IikgKwogIGxhYnMoeCA9ICJZZWFyIix5ID0gIkF2ZXJhZ2UgYW5udWFsIHRvdGFsXG5CcmF5IEN1cnRpcyBkaXNzaW1pbGFyaXR5IikgKwogIHlsaW0oMCwxLjUpICsKICB0aGVtZV9jbGFzc2ljKCkgKwogIGdndGl0bGUoIkF2ZXJhZ2UgbW9kZWwgcHJlZGljdGlvbnMgd2l0aCBtZWFuXG5vdmVyZWFsbCB0ZW1wZXJhdHVyZSBhbmQgZmlzaGluZyBwcmVzc3VyZSIpCgojbWVyZ2UgcGxvdHMKcHJlZGljdGVkX3ZhbHVlc19zYnRfamFjY2FyZF9maXNoaW5nX21lcmdlIDwtIGNvd3Bsb3Q6OnBsb3RfZ3JpZChwcmVkaWN0ZWRfdmFsdWVzX3RlbXBfZmlzaGluZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWRpY3RlZF92YWx1ZXNfdGVtcF9maXNoaW5nX21lYW50ZW1wZmlzaGluZ2luc3VydmV5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZGljdGVkX3ZhbHVlc190ZW1wX2Zpc2hpbmdfbWVhbnRlbXBmaXNoaW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmNvbCA9IDEpCgpnZ3NhdmUocHJlZGljdGVkX3ZhbHVlc19zYnRfamFjY2FyZF9maXNoaW5nX21lcmdlLCBwYXRoID0gaGVyZTo6aGVyZSgiZmlndXJlcyIpLCBmaWxlbmFtZSA9ICJwcmVkaWN0ZWRfdmFsdWVzX3NidF9qYWNjYXJkX2Zpc2hpbmdfbWVyZ2UuanBnIiwgaGVpZ2h0ID0gMzAsIHdpZHRoID0gMTQpCmBgYAoKVGFrZSBkaXNzaW1pbGFyaXR5IHZhbHVlcyBmcm9tIHJhbmRvbSBub3JtYWwgZGlzdHJpYnV0aW9uIGZvciBlYWNoIHllYXIgZm9yIGVhY2ggcmVnaW9uLCBhbmQgdGhlbiBjYWxjdWxhdGUgc2xvcGUgKDEwMDAgdGltZXMpLiBEbyB0aGlzIGZvcjoKIC0gRmlzaGluZyBhbmQgdGVtcGVyYXR1cmUgdmFyeSBpbnRlcmFubnVhbGx5IHdpdGhpbiBzdXJ2ZXlzCiAtIFRlbXBlcmF0dXJlIGlzIGhlbGQgY29uc3RhbnQgKGFzIG1lYW4gb3ZlciB0aW1lIHNlcmllcyBmb3IgYSBzdXJ2ZXkpLCBidXQgZmlzaGluZyB2YXJpZXMgKGFsbG93cyB1cyB0byBsb29rIGF0IHJlbGF0aXZlIHZhcmlhbmNlIGV4cGxhaW5lZCkKIC0gRmlzaGluZyBpcyBoZWxkIGNvbnN0YW50IChhcyBtZWFuIG92ZXIgdGltZSBzZXJpZXMgZm9yIGEgc3VydmV5KSwgYnV0IHRlbXBlcmF0dXJlIHZhcmllcyAoYWxsb3dzIHVzIHRvIGxvb2sgYXQgcmVsYXRpdmUgdmFyaWFuY2UgZXhwbGFpbmVkKQogLSBCb3RoIGZpc2hpbmcgYW5kIHRlbXBlcmF0dXJlIGhlbGQgY29uc3RhbnQgKGFsbG93cyB1cyB0byBzZWUgcm9sZSBvZiBvdGhlciBjb21wb25lbnRzIG9mIHRoZSBtb2RlbCkKIApgYGB7cn0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKI2Z1bGwgcHJlZGljdGlvbnMKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKI3RhYmxlIHdpdGggcHJlZGljdGVkIGRpc3NpbWlsYXJpdHkgdmFsdWVzIGFuZCBzdGFuZGFyZCBlcnJvciBvZiBhbGwgcHJlZGljdGVkIGRpc3NpbWlsYXJpdHkgdmFsdWVzIChieSB5ZWFyKQp0YWJsZSA8LSBkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0X3ByZWRpY3Rpb25zWywuKHN1cnZleV91bml0LCBwcmVkX2Rpc3NpbSwgcHJlZF9zZSwgeWVhcildCiMwKSBtYWtlIGRhdGF0YWJsZSB0byBwb3B1bGF0ZQogIHByZWRpY3RlZF9kaXNzaW1fdHJlbmRzX3Jub3JtcnVucyA8LSBkYXRhLnRhYmxlKCkKIzEpIE5FVyBQUkVESUNURUQgVkFMVUVTIEZST00gRElTVFJJQlVUSU9OCmZvciAoaSBpbiAxOjEwMDApewogIHRhYmxlWyxybm9ybV9wcmVkIDo9IHJub3JtKDEsIG1lYW4gPSBwcmVkX2Rpc3NpbSwgc2QgPSBwcmVkX3NlKSwuKHllYXIsIHN1cnZleV91bml0KV0KIzIpIENBTENVTEFURSBMSU5FQVIgTU9ERUwgVE8gRVhUUkFDVCBTVVJWRVkgU1BFQ0lGSUMgVFJFTkQgVkFMVUVTCiAgamFjY2FyZF90b3RhbF9wcmVkaWN0ZWRfbG1fc2luZ2xlcnVuIDwtIGxtKHJub3JtX3ByZWQgfiB5ZWFyKnN1cnZleV91bml0LGRhdGEgPSB0YWJsZSkKCiAgbW9kZWxfY29lZnNfcmVkdWNlZF9wcmVkaWN0aW9uc19zaW5nbGVydW4gPC0gZGF0YS50YWJsZShzdW1tYXJ5KGphY2NhcmRfdG90YWxfcHJlZGljdGVkX2xtX3NpbmdsZXJ1bikkY29lZmZpY2llbnRzKQogIG1vZGVsX2NvZWZzX3JlZHVjZWRfcHJlZGljdGlvbnNfc2luZ2xlcnVuWyx2YXIgOj0gcm93bmFtZXMoc3VtbWFyeShqYWNjYXJkX3RvdGFsX3ByZWRpY3RlZF9sbV9zaW5nbGVydW4pJGNvZWZmaWNpZW50cyldCiAgCiAgI2xpbWl0IHRvIGludGVyYWN0aW9ucyBvbmx5IChjaGVjayB0aGlzIGlmIHRoZXJlIGFyZSBhbnkgbW9kZWwgY2hhbmdlcyEpIHJvdyAyIGFuZCByb3dzIDM0OjY0CiAgbW9kZWxfY29lZnNfcmVkdWNlZF9wcmVkaWN0aW9uc19zaW5nbGVydW4gPC0gbW9kZWxfY29lZnNfcmVkdWNlZF9wcmVkaWN0aW9uc19zaW5nbGVydW5bYygyLDM0OjY0KSxdCiAgCiAgI2FkanVzdCBzdXJ2ZXkgdW5pdCBuYW1lIGJ5IGRlbGV0aW5nIGJlZ2lubmluZyBvZiBzdHJpbmcKICBtb2RlbF9jb2Vmc19yZWR1Y2VkX3ByZWRpY3Rpb25zX3NpbmdsZXJ1blssc3VydmV5X3VuaXQgOj0gc3Vic3RyKHZhciwgMTcsIHN0cl9sZW5ndGgodmFyKSldW3ZhciA9PSAieWVhciIsc3VydmV5X3VuaXQgOj0gIkFJIl0KICAKICAjY2FsY3VsYXRlIGludGVyYWN0aW9uIGNvZWZmaWNpZW50cwogIEFJX2VzdGltYXRlIDwtIG1vZGVsX2NvZWZzX3JlZHVjZWRfcHJlZGljdGlvbnNfc2luZ2xlcnVuWzEsRXN0aW1hdGVdCiAgbW9kZWxfY29lZnNfcmVkdWNlZF9wcmVkaWN0aW9uc19zaW5nbGVydW5bMSxlc3RpbWF0ZSA6PSBBSV9lc3RpbWF0ZV0KICBtb2RlbF9jb2Vmc19yZWR1Y2VkX3ByZWRpY3Rpb25zX3NpbmdsZXJ1blsyOjMyLGVzdGltYXRlIDo9IChBSV9lc3RpbWF0ZSArIEVzdGltYXRlKV0KICAKICBwcmVkaWN0ZWRfZGlzc2ltX3RyZW5kc19ybm9ybXJ1bnMgPC0gcmJpbmQocHJlZGljdGVkX2Rpc3NpbV90cmVuZHNfcm5vcm1ydW5zLCBtb2RlbF9jb2Vmc19yZWR1Y2VkX3ByZWRpY3Rpb25zX3NpbmdsZXJ1blssLihzdXJ2ZXlfdW5pdCwgZXN0aW1hdGUpXSkKICAKICBwcmludChpKQp9CiAgCiNyZWR1Y2UgdG8gbWVhbiBhbmQgc3RhbmRhcmQgZGV2aWF0aW9uCnByZWRpY3RlZF9kaXNzaW1fdHJlbmRzX3Jub3JtcnVuc1ssbWVhbl9kaXNzaW1fY29lZjo9IG1lYW4oZXN0aW1hdGUpLHN1cnZleV91bml0XVssc2RfZGlzc2ltIDo9IHNkKGVzdGltYXRlKSwuKHN1cnZleV91bml0KV0KCnByZWRpY3RlZF9kaXNzaW1fdHJlbmRzX3Jub3JtcnVucy5zdW1tYXJ5IDwtIHVuaXF1ZShwcmVkaWN0ZWRfZGlzc2ltX3RyZW5kc19ybm9ybXJ1bnNbLC4oc3VydmV5X3VuaXQsIG1lYW5fZGlzc2ltX2NvZWYsIHNkX2Rpc3NpbSldKQoKcHJlZGljdGVkX2Rpc3NpbV90cmVuZHNfcm5vcm1ydW5zLnN1bW1hcnlbLHByZWRfdHlwZSA6PSAiZnVsbCJdCgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojcHJlZGljdGlvbnMgd2l0aCB0ZW1wIGhlbGQgY29uc3RhbnQgYW5kIGZpc2hpbmcgc3RpbGwgdmFyeWluZyBmcm9tIHllYXIgdG8geWVhcgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojdGFibGUgd2l0aCBwcmVkaWN0ZWQgZGlzc2ltaWxhcml0eSB2YWx1ZXMgYW5kIHN0YW5kYXJkIGVycm9yIG9mIGFsbCBwcmVkaWN0ZWQgZGlzc2ltaWxhcml0eSB2YWx1ZXMgKGJ5IHllYXIpCnRhYmxlX2NvbnN0YW50dGVtcCA8LSBkaXNzaW1pbGFyaXR5X2NvdmFyaWF0ZXNfZHJlZGdlLmR0X3ByZWRpY3Rpb25zX2NvbnNpc3RlbnR0ZW1waW5yZWdbLC4oc3VydmV5X3VuaXQsIHByZWRfZGlzc2ltLCBwcmVkX3NlLCB5ZWFyKV0KIzApIG1ha2UgZGF0YXRhYmxlIHRvIHBvcHVsYXRlCiAgcHJlZGljdGVkX2Rpc3NpbV90cmVuZHNfcm5vcm1ydW5zX2NvbnN0YW50dGVtcCA8LSBkYXRhLnRhYmxlKCkKIzEpIE5FVyBQUkVESUNURUQgVkFMVUVTIEZST00gRElTVFJJQlVUSU9OCmZvciAoaSBpbiAxOjEwMDApewogIHRhYmxlX2NvbnN0YW50dGVtcFsscm5vcm1fcHJlZCA6PSBybm9ybSgxLCBtZWFuID0gcHJlZF9kaXNzaW0sIHNkID0gcHJlZF9zZSksLih5ZWFyLCBzdXJ2ZXlfdW5pdCldCiMyKSBDQUxDVUxBVEUgTElORUFSIE1PREVMIEZPUiBTTE9QRSBWQUxVRVMKICBqYWNjYXJkX3RvdGFsX3ByZWRpY3RlZF9sbV9zaW5nbGVydW5fY29uc3RhbnR0ZW1wIDwtIGxtKHJub3JtX3ByZWQgfiB5ZWFyKnN1cnZleV91bml0LGRhdGEgPSB0YWJsZV9jb25zdGFudHRlbXApCgogIG1vZGVsX2NvZWZzX3JlZHVjZWRfcHJlZGljdGlvbnNfc2luZ2xlcnVuX2NvbnN0YW50dGVtcCA8LSBkYXRhLnRhYmxlKHN1bW1hcnkoamFjY2FyZF90b3RhbF9wcmVkaWN0ZWRfbG1fc2luZ2xlcnVuX2NvbnN0YW50dGVtcCkkY29lZmZpY2llbnRzKQogIG1vZGVsX2NvZWZzX3JlZHVjZWRfcHJlZGljdGlvbnNfc2luZ2xlcnVuX2NvbnN0YW50dGVtcFssdmFyIDo9IHJvd25hbWVzKHN1bW1hcnkoamFjY2FyZF90b3RhbF9wcmVkaWN0ZWRfbG1fc2luZ2xlcnVuX2NvbnN0YW50dGVtcCkkY29lZmZpY2llbnRzKV0KICAKICAjbGltaXQgdG8gaW50ZXJhY3Rpb25zIG9ubHkgKGNoZWNrIHRoaXMgaWYgdGhlcmUgYXJlIGFueSBtb2RlbCBjaGFuZ2VzISkgcm93IDIgYW5kIHJvd3MgMzQ6NjQKICBtb2RlbF9jb2Vmc19yZWR1Y2VkX3ByZWRpY3Rpb25zX3NpbmdsZXJ1bl9jb25zdGFudHRlbXAgPC0gbW9kZWxfY29lZnNfcmVkdWNlZF9wcmVkaWN0aW9uc19zaW5nbGVydW5fY29uc3RhbnR0ZW1wW2MoMiwzNDo2NCksXQogIAogICNhZGp1c3Qgc3VydmV5IHVuaXQgbmFtZSBieSBkZWxldGluZyBiZWdpbm5pbmcgb2Ygc3RyaW5nCiAgbW9kZWxfY29lZnNfcmVkdWNlZF9wcmVkaWN0aW9uc19zaW5nbGVydW5fY29uc3RhbnR0ZW1wWyxzdXJ2ZXlfdW5pdCA6PSBzdWJzdHIodmFyLCAxNywgc3RyX2xlbmd0aCh2YXIpKV1bdmFyID09ICJ5ZWFyIixzdXJ2ZXlfdW5pdCA6PSAiQUkiXQogIAogICNjYWxjdWxhdGUgaW50ZXJhY3Rpb24gY29lZmZpY2llbnRzCiAgQUlfZXN0aW1hdGUgPC0gbW9kZWxfY29lZnNfcmVkdWNlZF9wcmVkaWN0aW9uc19zaW5nbGVydW5fY29uc3RhbnR0ZW1wWzEsRXN0aW1hdGVdCiAgbW9kZWxfY29lZnNfcmVkdWNlZF9wcmVkaWN0aW9uc19zaW5nbGVydW5fY29uc3RhbnR0ZW1wWzEsZXN0aW1hdGUgOj0gQUlfZXN0aW1hdGVdCiAgbW9kZWxfY29lZnNfcmVkdWNlZF9wcmVkaWN0aW9uc19zaW5nbGVydW5fY29uc3RhbnR0ZW1wWzI6MzIsZXN0aW1hdGUgOj0gKEFJX2VzdGltYXRlICsgRXN0aW1hdGUpXQogIAogIHByZWRpY3RlZF9kaXNzaW1fdHJlbmRzX3Jub3JtcnVuc19jb25zdGFudHRlbXAgPC0gcmJpbmQocHJlZGljdGVkX2Rpc3NpbV90cmVuZHNfcm5vcm1ydW5zX2NvbnN0YW50dGVtcCwgbW9kZWxfY29lZnNfcmVkdWNlZF9wcmVkaWN0aW9uc19zaW5nbGVydW5fY29uc3RhbnR0ZW1wWywuKHN1cnZleV91bml0LCBlc3RpbWF0ZSldKQogIAogIHByaW50KGkpCn0KICAKI3JlZHVjZSB0byBtZWFuIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24KcHJlZGljdGVkX2Rpc3NpbV90cmVuZHNfcm5vcm1ydW5zX2NvbnN0YW50dGVtcFssbWVhbl9kaXNzaW1fY29lZjo9IG1lYW4oZXN0aW1hdGUpLHN1cnZleV91bml0XVssc2RfZGlzc2ltIDo9IHNkKGVzdGltYXRlKSwuKHN1cnZleV91bml0KV0KCnByZWRpY3RlZF9kaXNzaW1fdHJlbmRzX3Jub3JtcnVuc2NvbnN0YW50X3RlbXAuc3VtbWFyeSA8LSB1bmlxdWUocHJlZGljdGVkX2Rpc3NpbV90cmVuZHNfcm5vcm1ydW5zX2NvbnN0YW50dGVtcFssLihzdXJ2ZXlfdW5pdCwgbWVhbl9kaXNzaW1fY29lZiwgc2RfZGlzc2ltKV0pCgpwcmVkaWN0ZWRfZGlzc2ltX3RyZW5kc19ybm9ybXJ1bnNjb25zdGFudF90ZW1wLnN1bW1hcnlbLHByZWRfdHlwZSA6PSAidGVtcF9jb25zdGFudCJdCgpwcmVkaWN0ZWRfZGlzc2ltX3RyZW5kc19ybm9ybXJ1bnMuc3VtbWFyeSA8LSByYmluZChwcmVkaWN0ZWRfZGlzc2ltX3RyZW5kc19ybm9ybXJ1bnMuc3VtbWFyeSwgcHJlZGljdGVkX2Rpc3NpbV90cmVuZHNfcm5vcm1ydW5zY29uc3RhbnRfdGVtcC5zdW1tYXJ5KQoKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKI3ByZWRpY3Rpb25zIHdpdGggZmlzaGluZyBoZWxkIGNvbnN0YW50IChhbmQgdGVtcGVyYXR1cmUgdmFyeWluZykKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKI3RhYmxlIHdpdGggcHJlZGljdGVkIGRpc3NpbWlsYXJpdHkgdmFsdWVzIGFuZCBzdGFuZGFyZCBlcnJvciBvZiBhbGwgcHJlZGljdGVkIGRpc3NpbWlsYXJpdHkgdmFsdWVzIChieSB5ZWFyKQp0YWJsZV9jb25zdGFudGZpc2hpbmcgPC0gZGlzc2ltaWxhcml0eV9jb3ZhcmlhdGVzX2RyZWRnZS5kdF9wcmVkaWN0aW9uc19jb25zaXN0ZW50ZmlzaGluZ2lucmVnWywuKHN1cnZleV91bml0LCBwcmVkX2Rpc3NpbSwgcHJlZF9zZSwgeWVhcildCiMwKSBtYWtlIGRhdGF0YWJsZSB0byBwb3B1bGF0ZQogIHByZWRpY3RlZF9kaXNzaW1fdHJlbmRzX3Jub3JtcnVuc19jb25zdGFudGZpc2hpbmcgPC0gZGF0YS50YWJsZSgpCiMxKSBORVcgUFJFRElDVEVEIFZBTFVFUyBGUk9NIERJU1RSSUJVVElPTgpmb3IgKGkgaW4gMToxMDAwKXsKICB0YWJsZV9jb25zdGFudGZpc2hpbmdbLHJub3JtX3ByZWQgOj0gcm5vcm0oMSwgbWVhbiA9IHByZWRfZGlzc2ltLCBzZCA9IHByZWRfc2UpLC4oeWVhciwgc3VydmV5X3VuaXQpXQojMikgQ0FMQ1VMQVRFIExJTkVBUiBNT0RFTCBGT1IgU0xPUEUgVkFMVUVTCiAgamFjY2FyZF90b3RhbF9wcmVkaWN0ZWRfbG1fc2luZ2xlcnVuX2NvbnN0YW50ZmlzaGluZyA8LSBsbShybm9ybV9wcmVkIH4geWVhcipzdXJ2ZXlfdW5pdCxkYXRhID0gdGFibGVfY29uc3RhbnRmaXNoaW5nKQoKICBtb2RlbF9jb2Vmc19yZWR1Y2VkX3ByZWRpY3Rpb25zX3NpbmdsZXJ1bl9jb25zdGFudGZpc2hpbmcgPC0gZGF0YS50YWJsZShzdW1tYXJ5KGphY2NhcmRfdG90YWxfcHJlZGljdGVkX2xtX3NpbmdsZXJ1bl9jb25zdGFudGZpc2hpbmcpJGNvZWZmaWNpZW50cykKICBtb2RlbF9jb2Vmc19yZWR1Y2VkX3ByZWRpY3Rpb25zX3NpbmdsZXJ1bl9jb25zdGFudGZpc2hpbmdbLHZhciA6PSByb3duYW1lcyhzdW1tYXJ5KGphY2NhcmRfdG90YWxfcHJlZGljdGVkX2xtX3NpbmdsZXJ1bl9jb25zdGFudGZpc2hpbmcpJGNvZWZmaWNpZW50cyldCiAgCiAgI2xpbWl0IHRvIGludGVyYWN0aW9ucyBvbmx5IChjaGVjayB0aGlzIGlmIHRoZXJlIGFyZSBhbnkgbW9kZWwgY2hhbmdlcyEpIHJvdyAyIGFuZCByb3dzIDM0OjY0CiAgbW9kZWxfY29lZnNfcmVkdWNlZF9wcmVkaWN0aW9uc19zaW5nbGVydW5fY29uc3RhbnRmaXNoaW5nIDwtIG1vZGVsX2NvZWZzX3JlZHVjZWRfcHJlZGljdGlvbnNfc2luZ2xlcnVuX2NvbnN0YW50ZmlzaGluZ1tjKDIsMzQ6NjQpLF0KICAKICAjYWRqdXN0IHN1cnZleSB1bml0IG5hbWUgYnkgZGVsZXRpbmcgYmVnaW5uaW5nIG9mIHN0cmluZwogIG1vZGVsX2NvZWZzX3JlZHVjZWRfcHJlZGljdGlvbnNfc2luZ2xlcnVuX2NvbnN0YW50ZmlzaGluZ1ssc3VydmV5X3VuaXQgOj0gc3Vic3RyKHZhciwgMTcsIHN0cl9sZW5ndGgodmFyKSldW3ZhciA9PSAieWVhciIsc3VydmV5X3VuaXQgOj0gIkFJIl0KICAKICAjY2FsY3VsYXRlIGludGVyYWN0aW9uIGNvZWZmaWNpZW50cwogIEFJX2VzdGltYXRlIDwtIG1vZGVsX2NvZWZzX3JlZHVjZWRfcHJlZGljdGlvbnNfc2luZ2xlcnVuX2NvbnN0YW50ZmlzaGluZ1sxLEVzdGltYXRlXQogIG1vZGVsX2NvZWZzX3JlZHVjZWRfcHJlZGljdGlvbnNfc2luZ2xlcnVuX2NvbnN0YW50ZmlzaGluZ1sxLGVzdGltYXRlIDo9IEFJX2VzdGltYXRlXQogIG1vZGVsX2NvZWZzX3JlZHVjZWRfcHJlZGljdGlvbnNfc2luZ2xlcnVuX2NvbnN0YW50ZmlzaGluZ1syOjMyLGVzdGltYXRlIDo9IChBSV9lc3RpbWF0ZSArIEVzdGltYXRlKV0KICAKICBwcmVkaWN0ZWRfZGlzc2ltX3RyZW5kc19ybm9ybXJ1bnNfY29uc3RhbnRmaXNoaW5nIDwtIHJiaW5kKHByZWRpY3RlZF9kaXNzaW1fdHJlbmRzX3Jub3JtcnVuc19jb25zdGFudGZpc2hpbmcsIG1vZGVsX2NvZWZzX3JlZHVjZWRfcHJlZGljdGlvbnNfc2luZ2xlcnVuX2NvbnN0YW50ZmlzaGluZ1ssLihzdXJ2ZXlfdW5pdCwgZXN0aW1hdGUpXSkKICAKICBwcmludChpKQp9CiAgCiNyZWR1Y2UgdG8gbWVhbiBhbmQgc3RhbmRhcmQgZGV2aWF0aW9uCnByZWRpY3RlZF9kaXNzaW1fdHJlbmRzX3Jub3JtcnVuc19jb25zdGFudGZpc2hpbmdbLG1lYW5fZGlzc2ltX2NvZWY6PSBtZWFuKGVzdGltYXRlKSxzdXJ2ZXlfdW5pdF1bLHNkX2Rpc3NpbSA6PSBzZChlc3RpbWF0ZSksLihzdXJ2ZXlfdW5pdCldCgpwcmVkaWN0ZWRfZGlzc2ltX3RyZW5kc19ybm9ybXJ1bnNjb25zdGFudF9maXNoaW5nLnN1bW1hcnkgPC0gdW5pcXVlKHByZWRpY3RlZF9kaXNzaW1fdHJlbmRzX3Jub3JtcnVuc19jb25zdGFudGZpc2hpbmdbLC4oc3VydmV5X3VuaXQsIG1lYW5fZGlzc2ltX2NvZWYsIHNkX2Rpc3NpbSldKQoKcHJlZGljdGVkX2Rpc3NpbV90cmVuZHNfcm5vcm1ydW5zY29uc3RhbnRfZmlzaGluZy5zdW1tYXJ5WyxwcmVkX3R5cGUgOj0gImZpc2hpbmdfY29uc3RhbnQiXQoKcHJlZGljdGVkX2Rpc3NpbV90cmVuZHNfcm5vcm1ydW5zLnN1bW1hcnkgPC0gcmJpbmQocHJlZGljdGVkX2Rpc3NpbV90cmVuZHNfcm5vcm1ydW5zLnN1bW1hcnksIHByZWRpY3RlZF9kaXNzaW1fdHJlbmRzX3Jub3JtcnVuc2NvbnN0YW50X2Zpc2hpbmcuc3VtbWFyeSkKCgojIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIwojcHJlZGljdGlvbnMgd2l0aCBib3RoIGZpc2hpbmcgYW5kIHRlbXBlcmF0dXJlIGhlbGQgY29uc3RhbnQgKHZhcmlhYmlsaXR5IGdvZXMgdG8gb3RoZXIgZmFjdG9ycyB3ZSBkb24ndCBhY2NvdW50IGZvcikKIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMKI3RhYmxlIHdpdGggcHJlZGljdGVkIGRpc3NpbWlsYXJpdHkgdmFsdWVzIGFuZCBzdGFuZGFyZCBlcnJvciBvZiBhbGwgcHJlZGljdGVkIGRpc3NpbWlsYXJpdHkgdmFsdWVzIChieSB5ZWFyKQp0YWJsZV9jb25zdGFudHRlbXBmaXNoaW5nIDwtIGRpc3NpbWlsYXJpdHlfY292YXJpYXRlc19kcmVkZ2UuZHRfcHJlZGljdGlvbnNfY29uc2lzdGVudHRlbXBmaXNoaW5naW5yZWdbLC4oc3VydmV5X3VuaXQsIHByZWRfZGlzc2ltLCBwcmVkX3NlLCB5ZWFyKV0KIzApIG1ha2UgZGF0YXRhYmxlIHRvIHBvcHVsYXRlCiAgcHJlZGljdGVkX2Rpc3NpbV90cmVuZHNfcm5vcm1ydW5zX2NvbnN0YW50dGVtcGZpc2hpbmcgPC0gZGF0YS50YWJsZSgpCiMxKSBORVcgUFJFRElDVEVEIFZBTFVFUyBGUk9NIERJU1RSSUJVVElPTgpmb3IgKGkgaW4gMToxMDAwKXsKICB0YWJsZV9jb25zdGFudHRlbXBmaXNoaW5nWyxybm9ybV9wcmVkIDo9IHJub3JtKDEsIG1lYW4gPSBwcmVkX2Rpc3NpbSwgc2QgPSBwcmVkX3NlKSwuKHllYXIsIHN1cnZleV91bml0KV0KIzIpIENBTENVTEFURSBMSU5FQVIgTU9ERUwgRk9SIFNMT1BFIFZBTFVFUwogIGphY2NhcmRfdG90YWxfcHJlZGljdGVkX2xtX3NpbmdsZXJ1bl9jb25zdGFudHRlbXBmaXNoaW5nIDwtIGxtKHJub3JtX3ByZWQgfiB5ZWFyKnN1cnZleV91bml0LGRhdGEgPSB0YWJsZV9jb25zdGFudHRlbXBmaXNoaW5nKQoKICBtb2RlbF9jb2Vmc19yZWR1Y2VkX3ByZWRpY3Rpb25zX3NpbmdsZXJ1bl9jb25zdGFudHRlbXBmaXNoaW5nIDwtIGRhdGEudGFibGUoc3VtbWFyeShqYWNjYXJkX3RvdGFsX3ByZWRpY3RlZF9sbV9zaW5nbGVydW5fY29uc3RhbnR0ZW1wZmlzaGluZykkY29lZmZpY2llbnRzKQogIG1vZGVsX2NvZWZzX3JlZHVjZWRfcHJlZGljdGlvbnNfc2luZ2xlcnVuX2NvbnN0YW50dGVtcGZpc2hpbmdbLHZhciA6PSByb3duYW1lcyhzdW1tYXJ5KGphY2NhcmRfdG90YWxfcHJlZGljdGVkX2xtX3NpbmdsZXJ1bl9jb25zdGFudHRlbXBmaXNoaW5nKSRjb2VmZmljaWVudHMpXQogIAogICNsaW1pdCB0byBpbnRlcmFjdGlvbnMgb25seSAoY2hlY2sgdGhpcyBpZiB0aGVyZSBhcmUgYW55IG1vZGVsIGNoYW5nZXMhKSByb3cgMiBhbmQgcm93cyAzNDo2NAogIG1vZGVsX2NvZWZzX3JlZHVjZWRfcHJlZGljdGlvbnNfc2luZ2xlcnVuX2NvbnN0YW50dGVtcGZpc2hpbmcgPC0gbW9kZWxfY29lZnNfcmVkdWNlZF9wcmVkaWN0aW9uc19zaW5nbGVydW5fY29uc3RhbnR0ZW1wZmlzaGluZ1tjKDIsMzQ6NjQpLF0KICAKICAjYWRqdXN0IHN1cnZleSB1bml0IG5hbWUgYnkgZGVsZXRpbmcgYmVnaW5uaW5nIG9mIHN0cmluZwogIG1vZGVsX2NvZWZzX3JlZHVjZWRfcHJlZGljdGlvbnNfc2luZ2xlcnVuX2NvbnN0YW50dGVtcGZpc2hpbmdbLHN1cnZleV91bml0IDo9IHN1YnN0cih2YXIsIDE3LCBzdHJfbGVuZ3RoKHZhcikpXVt2YXIgPT0gInllYXIiLHN1cnZleV91bml0IDo9ICJBSSJdCiAgCiAgI2NhbGN1bGF0ZSBpbnRlcmFjdGlvbiBjb2VmZmljaWVudHMKICBBSV9lc3RpbWF0ZSA8LSBtb2RlbF9jb2Vmc19yZWR1Y2VkX3ByZWRpY3Rpb25zX3NpbmdsZXJ1bl9jb25zdGFudHRlbXBmaXNoaW5nWzEsRXN0aW1hdGVdCiAgbW9kZWxfY29lZnNfcmVkdWNlZF9wcmVkaWN0aW9uc19zaW5nbGVydW5fY29uc3RhbnR0ZW1wZmlzaGluZ1sxLGVzdGltYXRlIDo9IEFJX2VzdGltYXRlXQogIG1vZGVsX2NvZWZzX3JlZHVjZWRfcHJlZGljdGlvbnNfc2luZ2xlcnVuX2NvbnN0YW50dGVtcGZpc2hpbmdbMjozMixlc3RpbWF0ZSA6PSAoQUlfZXN0aW1hdGUgKyBFc3RpbWF0ZSldCiAgCiAgcHJlZGljdGVkX2Rpc3NpbV90cmVuZHNfcm5vcm1ydW5zX2NvbnN0YW50dGVtcGZpc2hpbmcgPC0gcmJpbmQocHJlZGljdGVkX2Rpc3NpbV90cmVuZHNfcm5vcm1ydW5zX2NvbnN0YW50dGVtcGZpc2hpbmcsIG1vZGVsX2NvZWZzX3JlZHVjZWRfcHJlZGljdGlvbnNfc2luZ2xlcnVuX2NvbnN0YW50dGVtcGZpc2hpbmdbLC4oc3VydmV5X3VuaXQsIGVzdGltYXRlKV0pCiAgCiAgcHJpbnQoaSkKfQogIAojcmVkdWNlIHRvIG1lYW4gYW5kIHN0YW5kYXJkIGRldmlhdGlvbgpwcmVkaWN0ZWRfZGlzc2ltX3RyZW5kc19ybm9ybXJ1bnNfY29uc3RhbnR0ZW1wZmlzaGluZ1ssbWVhbl9kaXNzaW1fY29lZjo9IG1lYW4oZXN0aW1hdGUpLHN1cnZleV91bml0XVssc2RfZGlzc2ltIDo9IHNkKGVzdGltYXRlKSwuKHN1cnZleV91bml0KV0KCnByZWRpY3RlZF9kaXNzaW1fdHJlbmRzX3Jub3JtcnVuc2NvbnN0YW50X3RlbXBmaXNoaW5nLnN1bW1hcnkgPC0gdW5pcXVlKHByZWRpY3RlZF9kaXNzaW1fdHJlbmRzX3Jub3JtcnVuc19jb25zdGFudHRlbXBmaXNoaW5nWywuKHN1cnZleV91bml0LCBtZWFuX2Rpc3NpbV9jb2VmLCBzZF9kaXNzaW0pXSkKCnByZWRpY3RlZF9kaXNzaW1fdHJlbmRzX3Jub3JtcnVuc2NvbnN0YW50X3RlbXBmaXNoaW5nLnN1bW1hcnlbLHByZWRfdHlwZSA6PSAiZmlzaGluZ19hbmRfdGVtcF9jb25zdGFudCJdCgpwcmVkaWN0ZWRfZGlzc2ltX3RyZW5kc19ybm9ybXJ1bnMuc3VtbWFyeSA8LSByYmluZChwcmVkaWN0ZWRfZGlzc2ltX3RyZW5kc19ybm9ybXJ1bnMuc3VtbWFyeSwgcHJlZGljdGVkX2Rpc3NpbV90cmVuZHNfcm5vcm1ydW5zY29uc3RhbnRfdGVtcGZpc2hpbmcuc3VtbWFyeSkKYGBgCgpQbG90dGluZyBvYnNlcnZlZCB2cyBwcmVkaWN0ZWQKYGBge3J9CgpqYWNjYXJkX2Zpc2hpbmdfdGVtcF9tb2RlbF9vYnNlcnZlZF9wcmVkaWN0ZWRfZHQgPC0gamFjY2FyZF90b3RhbF9jb2Vmcy5yW3ByZWRpY3RlZF9kaXNzaW1fdHJlbmRzX3Jub3JtcnVucy5zdW1tYXJ5LCBvbiA9ICJzdXJ2ZXlfdW5pdCJdCgpqYWNjYXJkX2Zpc2hpbmdfdGVtcF9tb2RlbF9vYnNlcnZlZF9wcmVkaWN0ZWRfZHRbLHByZWRfbG93ZXIgOj0gbWVhbl9kaXNzaW1fY29lZi1zZF9kaXNzaW1dWyxwcmVkX3VwcGVyIDo9IG1lYW5fZGlzc2ltX2NvZWYrc2RfZGlzc2ltXQoKI0ZVTEwgTU9ERUwsIGJvdGggdGVtcGVyYXR1cmUgYW5kIGZpc2hpbmcgYXJlIGFsbG93ZWQgdG8gdmFyeQpqYWNjYXJkX2Zpc2hpbmdfdGVtcF9tb2RlbF9vYnNlcnZlZF9wcmVkaWN0ZWRfbG0gPC0gbG0oZXN0aW1hdGUgfiBtZWFuX2Rpc3NpbV9jb2VmLCBkYXRhID0gamFjY2FyZF9maXNoaW5nX3RlbXBfbW9kZWxfb2JzZXJ2ZWRfcHJlZGljdGVkX2R0W3ByZWRfdHlwZSA9PSAiZnVsbCJdKQpzdW1tYXJ5KGphY2NhcmRfZmlzaGluZ190ZW1wX21vZGVsX29ic2VydmVkX3ByZWRpY3RlZF9sbSkgI1JeMiAwLjU2CgooamFjY2FyZF9maXNoaW5nX3RlbXBfbW9kZWxfb2JzZXJ2ZWRfcHJlZGljdGVkIDwtIGdncGxvdChqYWNjYXJkX2Zpc2hpbmdfdGVtcF9tb2RlbF9vYnNlcnZlZF9wcmVkaWN0ZWRfZHRbcHJlZF90eXBlID09ICJmdWxsIl0pICsKICBnZW9tX2Vycm9yYmFyKGFlcyh4ID0gbWVhbl9kaXNzaW1fY29lZiwgeW1pbiA9IGx3ciwgeW1heCA9IHVwciksIGNvbG9yID0gImxpZ2h0Z3JleSIsIGxpbmV3aWR0aCA9IDAuNCkgKwogIGdlb21fZXJyb3JiYXJoKGFlcyh5ID0gZXN0aW1hdGUsIHhtaW4gPSBtZWFuX2Rpc3NpbV9jb2VmLXNkX2Rpc3NpbSwgeG1heCA9IG1lYW5fZGlzc2ltX2NvZWYrc2RfZGlzc2ltKSwgY29sb3IgPSAibGlnaHRncmV5IiwgbGluZXdpZHRoID0gMC40KSArCiAgZ2VvbV9wb2ludChhZXMoeSA9IGVzdGltYXRlLCB4ID0gbWVhbl9kaXNzaW1fY29lZikpICsKICBnZW9tX3Ntb290aChhZXMoeSA9IGVzdGltYXRlLCB4ID0gbWVhbl9kaXNzaW1fY29lZiksIGNvbG9yID0gImRhcmtncmV5IixsaW5ldHlwZSA9ICJkb3R0ZWQiLCBtZXRob2QgPSAibG0iKSArCiAgZ2VvbV9hYmxpbmUoYWVzKHNsb3BlID0gMSwgaW50ZXJjZXB0ID0gMCkpICsKICBsaW1zKHggPSBjKG1pbihqYWNjYXJkX2Zpc2hpbmdfdGVtcF9tb2RlbF9vYnNlcnZlZF9wcmVkaWN0ZWRfZHQkcHJlZF9sb3dlciksbWF4KGphY2NhcmRfZmlzaGluZ190ZW1wX21vZGVsX29ic2VydmVkX3ByZWRpY3RlZF9kdCRwcmVkX3VwcGVyKSkpICsKICBsYWJzKHkgPSAiT2JzZXJ2ZWQgzrItZGl2ZXJzaXR5IHRyZW5kIix4ID0gIlByZWRpY3RlZCDOsi1kaXZlcnNpdHkgdHJlbmRcbiIpICsKICB0aGVtZV9jbGFzc2ljKCkKKQoKI2Zpc2hpbmcgY29uc3RhbnQgKGZpc2hpbmcgY29uc3RhbnQ7IHRlbXBlcmF0dXJlIHZhcmllcyBvbmx5KQpqYWNjYXJkX2Zpc2hpbmdfY29uc3RhbnRfbW9kZWxfb2JzZXJ2ZWRfcHJlZGljdGVkX2xtIDwtIGxtKGVzdGltYXRlIH4gbWVhbl9kaXNzaW1fY29lZiwgZGF0YSA9IGphY2NhcmRfZmlzaGluZ190ZW1wX21vZGVsX29ic2VydmVkX3ByZWRpY3RlZF9kdFtwcmVkX3R5cGUgPT0gImZpc2hpbmdfY29uc3RhbnQiXSkKc3VtbWFyeShqYWNjYXJkX2Zpc2hpbmdfY29uc3RhbnRfbW9kZWxfb2JzZXJ2ZWRfcHJlZGljdGVkX2xtKSAKI1RlbXBlcmF0dXJlIGFzIGEgcHJlZGljdG9yLCBub3QgZmlzaGluZyA9IFJeMiA9IDAuNDAgKGRyb3AgaW4gMTYlIG9mIHZhcmlhbmNlIGV4cGxhaW5lZCB3aGVuIHlvdSBsb3NlIGZpc2hpbmcgYXMgcHJlZGljdG9yKQoKKGphY2NhcmRfZmlzaGluZ19jb25zdGFudF9tb2RlbF9vYnNlcnZlZF9wcmVkaWN0ZWQgPC0gZ2dwbG90KGphY2NhcmRfZmlzaGluZ190ZW1wX21vZGVsX29ic2VydmVkX3ByZWRpY3RlZF9kdFtwcmVkX3R5cGUgPT0gImZpc2hpbmdfY29uc3RhbnQiXSkgKwpnZW9tX2Vycm9yYmFyKGFlcyh4ID0gbWVhbl9kaXNzaW1fY29lZiwgeW1pbiA9IGx3ciwgeW1heCA9IHVwciksIGNvbG9yID0gImxpZ2h0Z3JleSIsIGxpbmV3aWR0aCA9IDAuNCkgKwogIGdlb21fZXJyb3JiYXJoKGFlcyh5ID0gZXN0aW1hdGUsIHhtaW4gPSBtZWFuX2Rpc3NpbV9jb2VmLXNkX2Rpc3NpbSwgeG1heCA9IG1lYW5fZGlzc2ltX2NvZWYrc2RfZGlzc2ltKSwgY29sb3IgPSAibGlnaHRncmV5IiwgbGluZXdpZHRoID0gMC40KSArCiAgZ2VvbV9wb2ludChhZXMoeSA9IGVzdGltYXRlLCB4ID0gbWVhbl9kaXNzaW1fY29lZikpICsKICAgIGdlb21fc21vb3RoKGFlcyh5ID0gZXN0aW1hdGUsIHggPSBtZWFuX2Rpc3NpbV9jb2VmKSwgY29sb3IgPSAiZGFya2dyZXkiLGxpbmV0eXBlID0gImRvdHRlZCIsIG1ldGhvZCA9ICJsbSIpICsKICBnZW9tX2FibGluZShhZXMoc2xvcGUgPSAxLCBpbnRlcmNlcHQgPSAwKSkgKwogICAgICBsaW1zKHggPSBjKG1pbihqYWNjYXJkX2Zpc2hpbmdfdGVtcF9tb2RlbF9vYnNlcnZlZF9wcmVkaWN0ZWRfZHQkcHJlZF9sb3dlciksbWF4KGphY2NhcmRfZmlzaGluZ190ZW1wX21vZGVsX29ic2VydmVkX3ByZWRpY3RlZF9kdCRwcmVkX3VwcGVyKSkpICsKICBsYWJzKHkgPSAiT2JzZXJ2ZWQgzrItZGl2ZXJzaXR5IHRyZW5kIix4ID0gIlByZWRpY3RlZCDOsi1kaXZlcnNpdHkgdHJlbmRcbih0ZW1wZXJhdHVyZSB2YXJpZXMgZmlzaGluZyBjb25zdGFudCkiKSArCiAgdGhlbWVfY2xhc3NpYygpCikKCiN0ZW1wIGNvbnN0YW50IChmaXNoaW5nIG9ubHk7IHRlbXBlcmF0dXJlIGNvbnN0YW50KQpqYWNjYXJkX3RlbXBlcmF0dXJlX2NvbnN0YW50X21vZGVsX29ic2VydmVkX3ByZWRpY3RlZF9sbSA8LSBsbShlc3RpbWF0ZSB+IG1lYW5fZGlzc2ltX2NvZWYsIGRhdGEgPSBqYWNjYXJkX2Zpc2hpbmdfdGVtcF9tb2RlbF9vYnNlcnZlZF9wcmVkaWN0ZWRfZHRbcHJlZF90eXBlID09ICJ0ZW1wX2NvbnN0YW50Il0pCnN1bW1hcnkoamFjY2FyZF90ZW1wZXJhdHVyZV9jb25zdGFudF9tb2RlbF9vYnNlcnZlZF9wcmVkaWN0ZWRfbG0pICMwLjI2IERyb3AgaW4gMzAlIG9mIHZhcmlhbmNlIGV4cGxhaW5lZCB3aGVuIHlvdSBsb3NlIHRlbXBlcmF0dXJlIGFzIGEgcHJlZGljdG9yCgooamFjY2FyZF90ZW1wZXJhdHVyZV9jb25zdGFudF9tb2RlbF9vYnNlcnZlZF9wcmVkaWN0ZWQgPC0gZ2dwbG90KGphY2NhcmRfZmlzaGluZ190ZW1wX21vZGVsX29ic2VydmVkX3ByZWRpY3RlZF9kdFtwcmVkX3R5cGUgPT0gInRlbXBfY29uc3RhbnQiXSkgKwogIGdlb21fZXJyb3JiYXIoYWVzKHggPSBtZWFuX2Rpc3NpbV9jb2VmLCB5bWluID0gbHdyLCB5bWF4ID0gdXByKSwgY29sb3IgPSAibGlnaHRncmV5IiwgbGluZXdpZHRoID0gMC40KSArCiAgZ2VvbV9lcnJvcmJhcmgoYWVzKHkgPSBlc3RpbWF0ZSwgeG1pbiA9IG1lYW5fZGlzc2ltX2NvZWYtc2RfZGlzc2ltLCB4bWF4ID0gbWVhbl9kaXNzaW1fY29lZitzZF9kaXNzaW0pLCBjb2xvciA9ICJsaWdodGdyZXkiLCBsaW5ld2lkdGggPSAwLjQpICsKICBnZW9tX3BvaW50KGFlcyh5ID0gZXN0aW1hdGUsIHggPSBtZWFuX2Rpc3NpbV9jb2VmKSkgKwogICAgZ2VvbV9zbW9vdGgoYWVzKHkgPSBlc3RpbWF0ZSwgeCA9IG1lYW5fZGlzc2ltX2NvZWYpLCBjb2xvciA9ICJkYXJrZ3JleSIsbGluZXR5cGUgPSAiZG90dGVkIiwgbWV0aG9kID0gImxtIikgKwogIGdlb21fYWJsaW5lKGFlcyhzbG9wZSA9IDEsIGludGVyY2VwdCA9IDApKSArCiAgICAgIGxpbXMoeCA9IGMobWluKGphY2NhcmRfZmlzaGluZ190ZW1wX21vZGVsX29ic2VydmVkX3ByZWRpY3RlZF9kdCRwcmVkX2xvd2VyKSxtYXgoamFjY2FyZF9maXNoaW5nX3RlbXBfbW9kZWxfb2JzZXJ2ZWRfcHJlZGljdGVkX2R0JHByZWRfdXBwZXIpKSkgKwogIGxhYnMoeSA9ICJPYnNlcnZlZCDOsi1kaXZlcnNpdHkgdHJlbmQiLHggPSAiUHJlZGljdGVkIM6yLWRpdmVyc2l0eSB0cmVuZFxuKGZpc2hpbmcgdmFyaWVzIHRlbXBlcmF0dXJlIGNvbnN0YW50KSIpICsKICB0aGVtZV9jbGFzc2ljKCkKKQoKI2JvdGggdGVtcGVyYXR1cmUgYW5kIGZpc2ggaGVsZCBjb25zdGFudApqYWNjYXJkX2Zpc2hpbmdfdGVtcF9tb2RlbF9vYnNlcnZlZF9wcmVkaWN0ZWRfdGVtcGZpc2hjb25zdGFudGluc3VydmV5X2xtIDwtIGxtKGVzdGltYXRlIH4gbWVhbl9kaXNzaW1fY29lZiwgZGF0YSA9IGphY2NhcmRfZmlzaGluZ190ZW1wX21vZGVsX29ic2VydmVkX3ByZWRpY3RlZF9kdFtwcmVkX3R5cGUgPT0gImZpc2hpbmdfYW5kX3RlbXBfY29uc3RhbnQiXSkKc3VtbWFyeShqYWNjYXJkX2Zpc2hpbmdfdGVtcF9tb2RlbF9vYnNlcnZlZF9wcmVkaWN0ZWRfdGVtcGZpc2hjb25zdGFudGluc3VydmV5X2xtKSAjJTIwICNkcm9wIG9mIDM2IGZyb20gZnVsbAoKKGphY2NhcmRfZmlzaGluZ190ZW1wX21vZGVsX29ic2VydmVkX3ByZWRpY3RlZF90ZW1wZmlzaGNvbnN0YW50aW5zdXJ2ZXkgPC0gZ2dwbG90KGphY2NhcmRfZmlzaGluZ190ZW1wX21vZGVsX29ic2VydmVkX3ByZWRpY3RlZF9kdFtwcmVkX3R5cGUgPT0gImZpc2hpbmdfYW5kX3RlbXBfY29uc3RhbnQiXSkgKwpnZW9tX2Vycm9yYmFyKGFlcyh4ID0gbWVhbl9kaXNzaW1fY29lZiwgeW1pbiA9IGx3ciwgeW1heCA9IHVwciksIGNvbG9yID0gImxpZ2h0Z3JleSIsIGxpbmV3aWR0aCA9IDAuNCkgKwogIGdlb21fZXJyb3JiYXJoKGFlcyh5ID0gZXN0aW1hdGUsIHhtaW4gPSBtZWFuX2Rpc3NpbV9jb2VmLXNkX2Rpc3NpbSwgeG1heCA9IG1lYW5fZGlzc2ltX2NvZWYrc2RfZGlzc2ltKSwgY29sb3IgPSAibGlnaHRncmV5IiwgbGluZXdpZHRoID0gMC40KSArCiAgZ2VvbV9wb2ludChhZXMoeSA9IGVzdGltYXRlLCB4ID0gbWVhbl9kaXNzaW1fY29lZikpICsKICAgIGdlb21fc21vb3RoKGFlcyh5ID0gZXN0aW1hdGUsIHggPSBtZWFuX2Rpc3NpbV9jb2VmKSwgY29sb3IgPSAiZGFya2dyZXkiLGxpbmV0eXBlID0gImRvdHRlZCIsIG1ldGhvZCA9ICJsbSIpKwogIGdlb21fYWJsaW5lKGFlcyhzbG9wZSA9IDEsIGludGVyY2VwdCA9IDApKSArCiAgICAgIGxpbXMoeCA9IGMobWluKGphY2NhcmRfZmlzaGluZ190ZW1wX21vZGVsX29ic2VydmVkX3ByZWRpY3RlZF9kdCRwcmVkX2xvd2VyKSxtYXgoamFjY2FyZF9maXNoaW5nX3RlbXBfbW9kZWxfb2JzZXJ2ZWRfcHJlZGljdGVkX2R0JHByZWRfdXBwZXIpKSkgKwogIGxhYnMoeSA9ICJPYnNlcnZlZCDOsi1kaXZlcnNpdHkgdHJlbmQiLHggPSAiUHJlZGljdGVkIM6yLWRpdmVyc2l0eSB0cmVuZFxuKGZpc2hpbmcgYW5kIHRlbXBlcmF0dXJlIGNvbnN0YW50KSIpICsKICB0aGVtZV9jbGFzc2ljKCkKKQoKCiNtZXJnZQpqYWNjYXJkX2Zpc2hpbmdfc2J0X21vZGVsX29ic2VydmVkX3ByZWRpY3RlZF9tZXJnZSA8LSBwbG90X2dyaWQoamFjY2FyZF9maXNoaW5nX3RlbXBfbW9kZWxfb2JzZXJ2ZWRfcHJlZGljdGVkICsgdGhlbWUocGxvdC5tYXJnaW4gPSB1bml0KGMoMC4xLDAuMywwLjEsMC4xKSwiY20iKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGphY2NhcmRfZmlzaGluZ19jb25zdGFudF9tb2RlbF9vYnNlcnZlZF9wcmVkaWN0ZWQgKyB0aGVtZShwbG90Lm1hcmdpbiA9IHVuaXQoYygwLjEsMC4zLDAuMSwwLjEpLCJjbSIpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgamFjY2FyZF90ZW1wZXJhdHVyZV9jb25zdGFudF9tb2RlbF9vYnNlcnZlZF9wcmVkaWN0ZWQgKyB0aGVtZShwbG90Lm1hcmdpbiA9IHVuaXQoYygwLjEsMC4zLDAuMSwwLjEpLCJjbSIpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgamFjY2FyZF9maXNoaW5nX3RlbXBfbW9kZWxfb2JzZXJ2ZWRfcHJlZGljdGVkX3RlbXBmaXNoY29uc3RhbnRpbnN1cnZleSArIHRoZW1lKHBsb3QubWFyZ2luID0gdW5pdChjKDAuMSwwLjMsMC4xLDAuMSksImNtIikpLCBuY29sID0gMiwgbGFiZWxzID0gYygiYS4iLCJiLiIsImMuIiwiZC4iKSkKCmdnc2F2ZShqYWNjYXJkX2Zpc2hpbmdfc2J0X21vZGVsX29ic2VydmVkX3ByZWRpY3RlZF9tZXJnZSwgcGF0aCA9IGhlcmU6OmhlcmUoImZpZ3VyZXMiKSxmaWxlbmFtZSA9ICJqYWNjYXJkX2Zpc2hpbmdfc2J0X21vZGVsX29ic2VydmVkX3ByZWRpY3RlZF9tZXJnZS5qcGciLCBoZWlnaHQgPTYsIHdpZHRoID0gOCkKCgpgYGAKCkxldCdzIHZpc3VhbGl6ZSBtb2RlbCBjb2VmZmljaWVudHMgd2l0aCB0ZW1wZXJhdHVyZSBhbmQgZmlzaGluZyAoc2ltaWxhciB0byBmaWd1cmUgMikKbW9kZWxfYXZnX3ZhbHVlcwpgYGB7cn0KbW9kZWxfYXZnX3ZhbHVlcwoKI2V4dHJhY3QgY29lZmZpY2llbnRzIHVzaW5nIGxpbmVhciBhbGdlYnJhCmludGVyYWN0aW9uX2F2Z19tb2RlbF9jb2VmIDwtIGRhdGEudGFibGUobG1faW50ZXJhY3Rpb25fY29lZmZpY2llbnRzX3NlKG1vZF9uYW1lID0gbW9kZWxfYXZnX2RlbHRhNCwgbW9kZWxfYXZnID0gVCwgU0JUX2Zpc2ggPSBUKSkKCiNhZGQgc3VydmV5IG5hbWVzCmludGVyYWN0aW9uX2F2Z19tb2RlbF9jb2VmWyxzdXJ2ZXlfdW5pdCA6PSBmYWN0b3IoYyhhbGxfc3VydmV5c1shYWxsX3N1cnZleXMgJWluJSBjKCJST0NLQUxMIiwgIkdTTC1TIildLGFsbF9zdXJ2ZXlzWyFhbGxfc3VydmV5cyAlaW4lIGMoIlJPQ0tBTEwiLCAiR1NMLVMiKV0pKV0KCiNhZGQgcHJlZGljdG9yIG5hbWVzCmludGVyYWN0aW9uX2F2Z19tb2RlbF9jb2VmWyxwcmVkaWN0b3IgOj0gYyhyZXAoIlJlbGF0aXZlIGZpc2hpbmcgY2F0Y2giLDMyKSxyZXAoIk1pbmltdW0gdGVtcGVyYXR1cmUiLDMyKSldCgojcmVvcmRlciB0ZW1wZXJhdHVyZSBhbmQgZmlzaGluZwppbnRlcmFjdGlvbl9hdmdfbW9kZWxfY29lZlsscHJlZGljdG9yIDo9IGZhY3RvcihwcmVkaWN0b3IsIGxldmVscyA9IGMoIk1pbmltdW0gdGVtcGVyYXR1cmUiLCJSZWxhdGl2ZSBmaXNoaW5nIGNhdGNoIikpXQoKI2xpbmsgZm9yIGZ1bGwgc3VydmV5IG5hbWUKaW50ZXJhY3Rpb25fYXZnX21vZGVsX2NvZWYgPC0gY29sb3JfbGlua1tpbnRlcmFjdGlvbl9hdmdfbW9kZWxfY29lZiwgb24gPSAic3VydmV5X3VuaXQiXQoKI2xpc3Qgb2YgU3VydmV5IE5hbWUgU2Vhc29uIGluIG9yZGVyIGJ5IHN1cnZleSB1bml0CnNldGtleShpbnRlcmFjdGlvbl9hdmdfbW9kZWxfY29lZiwgc3VydmV5X3VuaXQpCgpzdXJ2ZXlfbmFtZV9zZWFzb25fb3JkZXJlZCA8LSB1bmlxdWUoaW50ZXJhY3Rpb25fYXZnX21vZGVsX2NvZWYkU3VydmV5X05hbWVfU2Vhc29uKQoKI01ha2UgU3VydmV5X05hbWVfU2Vhc29uIGEgZmFjdG9yCmludGVyYWN0aW9uX2F2Z19tb2RlbF9jb2VmWyxTdXJ2ZXlfTmFtZV9TZWFzb24gOj0gZmFjdG9yKFN1cnZleV9OYW1lX1NlYXNvbiwgbGV2ZWxzID0gc3VydmV5X25hbWVfc2Vhc29uX29yZGVyZWQpXQoKCiNtYXJrIHNpZ25pZmljYW5jZQppbnRlcmFjdGlvbl9hdmdfbW9kZWxfY29lZlssU2lnbmlmaWNhbnQgOj0gaWZlbHNlKChlc3RpbWF0ZS1zZSA+IDAgJiBlc3RpbWF0ZStzZSA+IDApIHwgKGVzdGltYXRlLXNlIDwgMCAmIGVzdGltYXRlK3NlIDwgMCksVCxGKV0KCgojUGxvdCBib3RoCnNidF9maXNoaW5nX2F2Z19tb2RlbF9jb2VmIDwtIGdncGxvdCgpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBsaW5ldHlwZSA9ICJkb3R0ZWQiKSArCmdlb21fcG9pbnQoZGF0YSA9IGludGVyYWN0aW9uX2F2Z19tb2RlbF9jb2VmLCBhZXMoeCA9IFN1cnZleV9OYW1lX1NlYXNvbiwgeSA9IGVzdGltYXRlLCBjb2xvciA9IFNpZ25pZmljYW50KSkgKyAgCmdlb21fZXJyb3JiYXIoZGF0YSA9IGludGVyYWN0aW9uX2F2Z19tb2RlbF9jb2VmLCBhZXMoeCA9IFN1cnZleV9OYW1lX1NlYXNvbiwgeW1pbiA9IGVzdGltYXRlLXNlLCB5bWF4ID0gZXN0aW1hdGUrc2UsIGNvbG9yID0gU2lnbmlmaWNhbnQpLCB3aWR0aCA9IDApICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiZGFya2dyZXkiLCJibGFjayIpKSArCmZhY2V0X3dyYXAofnByZWRpY3Rvciwgc2NhbGVzID0gImZyZWVfeCIpICsKc2NhbGVfeF9kaXNjcmV0ZShsaW1pdHMgPSByZXYpICsKICBsYWJzKHkgPSAiQ29lZmZpY2llbnQiLCB4ID0gIiIpICsKY29vcmRfZmxpcCgpICsKdGhlbWVfY2xhc3NpYygpCiAgCgoKYGBgCgpQbG90IGFsbCBvdGhlciBjb2VmZmljaWVudHMgaW4gYXZlcmFnZWQgbW9kZWwKYGBge3J9Cm1vZGVsX2F2Z192YWx1ZXMubm9uZmlzaG9ydGVtcCA8LSBtb2RlbF9hdmdfdmFsdWVzW2MoMiw2LDEwMjoxMDYpLF0KCiNtYXJrIHNpZ25pZmljYW5jZQptb2RlbF9hdmdfdmFsdWVzLm5vbmZpc2hvcnRlbXBbLFNpZ25pZmljYW50IDo9IGlmZWxzZSgoY29lZi1zZSA+IDAgJiBjb2VmK3NlID4gMCkgfCAoY29lZi1zZSA8IDAgJiBjb2VmK3NlIDwgMCksVCxGKV0KCiNtb3JlIGhlbHBmdWwgbmFtZXMgZm9yIHZhcmlhYmxlcwptb2RlbF9hdmdfdmFsdWVzLm5vbmZpc2hvcnRlbXBbLFZhcmlhYmxlIDo9IGMoIkFyZWEiLCJTcGVjaWVzIGNvdW50IiwiRGVwdGgiLCJOdW1iZXIgb2YgdG93cyIsIkxhdGl0dWRlIiwiRGVwdGggcmFuZ2UiLCJMYXRpdHVkZSByYW5nZSIpXQoKI21ha2UgZmFjdG9yIHdpdGggb3JkZXIKbW9kZWxfYXZnX3ZhbHVlcy5ub25maXNob3J0ZW1wWyxWYXJpYWJsZSA6PSBmYWN0b3IoVmFyaWFibGUsIGxldmVscyA9IGMoIkFyZWEiLCJTcGVjaWVzIGNvdW50IiwiTnVtYmVyIG9mIHRvd3MiLCJEZXB0aCIsIkRlcHRoIHJhbmdlIiwiTGF0aXR1ZGUiLCJMYXRpdHVkZSByYW5nZSIpKV0KCgojcGxvdAphbGxfYXZnX21vZGVsX2NvZWYgPC0gZ2dwbG90KCkgKyAKZ2VvbV9wb2ludChkYXRhID0gbW9kZWxfYXZnX3ZhbHVlcy5ub25maXNob3J0ZW1wLCBhZXMoeCA9IFZhcmlhYmxlLCB5ID0gY29lZiwgY29sb3IgPSBTaWduaWZpY2FudCkpICsgIApnZW9tX2Vycm9yYmFyKGRhdGEgPSBtb2RlbF9hdmdfdmFsdWVzLm5vbmZpc2hvcnRlbXAsIGFlcyh4ID0gVmFyaWFibGUsIHltaW4gPSBjb2VmLXNlLCB5bWF4ID0gY29lZitzZSwgY29sb3IgPSBTaWduaWZpY2FudCksIHdpZHRoID0gMCkgKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJkYXJrZ3JleSIsImJsYWNrIikpICsKZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMCkgKwpzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IHJldikgKwogIGxhYnMoeSA9ICJDb2VmZmljaWVudCIsIHggPSAiXG5cblxuIikgKwpjb29yZF9mbGlwKCkgKwp0aGVtZV9jbGFzc2ljKCkKCiNwbG90CmFsbF9idXRfbGF0X2F2Z19tb2RlbF9jb2VmIDwtIGdncGxvdCgpICsgCmdlb21fcG9pbnQoZGF0YSA9IG1vZGVsX2F2Z192YWx1ZXMubm9uZmlzaG9ydGVtcFtWYXJpYWJsZSA9PSAiTGF0aXR1ZGUiXSwgYWVzKHggPSBWYXJpYWJsZSwgeSA9IGNvZWYsIGNvbG9yID0gU2lnbmlmaWNhbnQpKSArICAKZ2VvbV9lcnJvcmJhcihkYXRhID0gbW9kZWxfYXZnX3ZhbHVlcy5ub25maXNob3J0ZW1wW1ZhcmlhYmxlID09ICJMYXRpdHVkZSJdLCBhZXMoeCA9IFZhcmlhYmxlLCB5bWluID0gY29lZi1zZSwgeW1heCA9IGNvZWYrc2UsIGNvbG9yID0gU2lnbmlmaWNhbnQpLCB3aWR0aCA9IDApICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygiZGFya2dyZXkiLCJibGFjayIpKSArCmdlb21faGxpbmUoeWludGVyY2VwdCA9IDApICsKc2NhbGVfeF9kaXNjcmV0ZShsaW1pdHMgPSByZXYpICsKICBsYWJzKHkgPSAiQ29lZmZpY2llbnQiLCB4ID0gIk1vZGVsIHZhcmlhYmxlIikgKwpjb29yZF9mbGlwKCkgKwp0aGVtZV9jbGFzc2ljKCkKCiNwbG90CmxhdF9hdmdfbW9kZWxfY29lZiA8LSBnZ3Bsb3QoKSArIApnZW9tX3BvaW50KGRhdGEgPSBtb2RlbF9hdmdfdmFsdWVzLm5vbmZpc2hvcnRlbXBbVmFyaWFibGUgIT0gIkxhdGl0dWRlIl0sIGFlcyh4ID0gVmFyaWFibGUsIHkgPSBjb2VmLCBjb2xvciA9IFNpZ25pZmljYW50KSkgKyAgCmdlb21fZXJyb3JiYXIoZGF0YSA9IG1vZGVsX2F2Z192YWx1ZXMubm9uZmlzaG9ydGVtcFtWYXJpYWJsZSAhPSAiTGF0aXR1ZGUiXSwgYWVzKHggPSBWYXJpYWJsZSwgeW1pbiA9IGNvZWYtc2UsIHltYXggPSBjb2VmK3NlLCBjb2xvciA9IFNpZ25pZmljYW50KSwgd2lkdGggPSAwKSArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoImRhcmtncmV5IiwiYmxhY2siKSkgKwpnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwKSArCnNjYWxlX3hfZGlzY3JldGUobGltaXRzID0gcmV2KSArCiAgbGFicyh5ID0gIkNvZWZmaWNpZW50IiwgeCA9ICJNb2RlbCB2YXJpYWJsZSIpICsKY29vcmRfZmxpcCgpICsKdGhlbWVfY2xhc3NpYygpCgojbWVyZ2UgaW50byBzaW5nbGUgcGxvdAoKbW9kZWxfY29lZl9zdW1tYXJ5X3NidF9qYWNjYXJkIDwtIGNvd3Bsb3Q6OnBsb3RfZ3JpZChzYnRfZmlzaGluZ19hdmdfbW9kZWxfY29lZit0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibnVsbCIsIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSksYWxsX2F2Z19tb2RlbF9jb2VmK3RoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJudWxsIiksIG5jb2wgPSAxLCBsYWJlbHMgPSBjKCIgIGEuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYi4iLCIgICAgICAgIGMuIiksIGxhYmVsX3kgPSAwLjk5LCByZWxfaGVpZ2h0cyA9IGMoMywxKSkKCmdnc2F2ZShtb2RlbF9jb2VmX3N1bW1hcnlfc2J0X2phY2NhcmQsIHBhdGggPSBoZXJlOjpoZXJlKCJmaWd1cmVzIiksZmlsZW5hbWUgPSAibW9kZWxfY29lZl9zdW1tYXJ5X3NidF9qYWNjYXJkLmpwZyIsIGhlaWdodCA9IDYuNSwgd2lkdGggPSA4LCB1bml0ID0gImluIikKCgpgYGAKCiNJRiBXRSBBQ1RVQUxMWSBVU0UgVEhJUywgTkVFRCBUTyBVUERBVEUKIyNTaG93IGludGVyY2VwdHMgYnkgcmVnaW9uIGFuZCBzZWFzb24KIwojYGBge3J9CiMKIyNzdXJ2ZXkgaW50ZXJjZXB0cwojc3VydmV5X2ludGVyY2VwdHMgPC0gbW9kZWxfYXZnX3ZhbHVlc1tjKDEsODozOCksLihjb2VmX25hbWUsIGNvZWYsIHNlKV0KI3N1cnZleV9pbnRlcmNlcHRzWzEsc3VydmV5X3VuaXQgOj0gIkFJIl1bMSxjb2VmX3RydWUgOj0gY29lZl0KI3N1cnZleV9pbnRlcmNlcHRzWzI6MzIsc3VydmV5X3VuaXQgOj0gc3Vic3RyKGNvZWZfbmFtZSwgMTIsIHN0cl9sZW5ndGgoY29lZl9uYW1lKSldWzI6MzIsY29lZl90cnVlIDo9IHN1cnZleV9pbnRlcmNlcHRzWzEsY29lZl90cnVlXStjb2VmXQojc3VydmV5X2ludGVyY2VwdHMgPC0gY29sb3JfbGlua1tzdXJ2ZXlfaW50ZXJjZXB0cywgb24gPSAic3VydmV5X3VuaXQiXQojc3VydmV5X2ludGVyY2VwdHNbLFN1cnZleV9OYW1lX1NlYXNvbiA6PSByZW9yZGVyKFN1cnZleV9OYW1lX1NlYXNvbiwgY29lZl90cnVlKV0KIwojCiMjc2Vhc29uX2ludGVyY2VwdHMKI3NlYXNvbl9pbnRlcmNlcHRzIDwtIG1vZGVsX2F2Z192YWx1ZXNbYygxLDM6NSksLihjb2VmX25hbWUsIGNvZWYsIHNlKV0KI3NlYXNvbl9pbnRlcmNlcHRzWzEsc2Vhc29uIDo9ICJTcHJpbmciXVsxLGNvZWZfdHJ1ZSA6PSBjb2VmXQojc2Vhc29uX2ludGVyY2VwdHNbMjo0LHNlYXNvbiA6PSBzdWJzdHIoY29lZl9uYW1lLCA3LCBzdHJfbGVuZ3RoKGNvZWZfbmFtZSkpXVsyOjQsY29lZl90cnVlIDo9IHNlYXNvbl9pbnRlcmNlcHRzWzEsY29lZl90cnVlXStjb2VmXQojc2Vhc29uX2ludGVyY2VwdHNbLHNlYXNvbiA6PSByZW9yZGVyKHNlYXNvbiwgY29lZl90cnVlKV0KIwojCiMjc3VydmV5IGludGVyY2VwdHMKI3N1cnZleV9tb2RlbF9jb2VmIDwtIGdncGxvdCgpICsKI2dlb21fcG9pbnQoZGF0YSA9IHN1cnZleV9pbnRlcmNlcHRzLCBhZXMoeCA9IFN1cnZleV9OYW1lX1NlYXNvbiwgeSA9IGNvZWZfdHJ1ZSkpICsgIAojZ2VvbV9lcnJvcmJhcihkYXRhID0gc3VydmV5X2ludGVyY2VwdHMsIGFlcyh4ID0gU3VydmV5X05hbWVfU2Vhc29uLCB5bWluID0gY29lZl90cnVlLXNlLCB5bWF4ID0gY29lZl90cnVlK3NlKSwgd2lkdGggPSAwKSArCiNzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cyA9IHJldikgKwojIyAgeWxpbSgwLjM1LDEpICsKIyAgbGFicyh5ID0gIkludGVyY2VwdCIsIHggPSAiIikgKwojY29vcmRfZmxpcCgpICsKI3RoZW1lX2NsYXNzaWMoKQojICAKIyNzZWFzb24gaW50ZXJjZXB0cwojc2Vhc29uX21vZGVsX2NvZWYgPC0gZ2dwbG90KCkgKwojZ2VvbV9wb2ludChkYXRhID0gc2Vhc29uX2ludGVyY2VwdHMsIGFlcyh4ID0gc2Vhc29uLCB5ID0gY29lZl90cnVlKSkgKyAgCiNnZW9tX2Vycm9yYmFyKGRhdGEgPSBzZWFzb25faW50ZXJjZXB0cywgYWVzKHggPSBzZWFzb24sIHltaW4gPSBjb2VmX3RydWUtc2UsIHltYXggPSBjb2VmX3RydWUrc2UpLCB3aWR0aCA9IDApICsKI3NjYWxlX3hfZGlzY3JldGUobGltaXRzID0gcmV2KSArCiMgIyB5bGltKDAuMzUsMSkgKwojICBsYWJzKHkgPSAiSW50ZXJjZXB0IiwgeCA9ICIiKSArCiNjb29yZF9mbGlwKCkgKwojdGhlbWVfY2xhc3NpYygpCiMKIyNtZXJnZSBpbnRvIHNpbmdsZSBwbG90CiMKI21vZGVsX2ludGVyY2VwdF9qYWNjYXJkIDwtIGNvd3Bsb3Q6OnBsb3RfZ3JpZChzdXJ2ZXlfbW9kZWxfY29lZit0aGVtZShheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCkpLAojICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWFzb25fbW9kZWxfY29lZiwgbmNvbCA9IDEsIGxhYmVscyA9IGMoImEuIiwiYi4iKSwgbGFiZWxfeSA9IDAuOTksIHJlbF9oZWlnaHRzID0gYygzLDEpLCBhbGlnbiA9ICJ2IikKIwojZ2dzYXZlKG1vZGVsX2ludGVyY2VwdF9qYWNjYXJkLCBwYXRoID0gaGVyZTo6aGVyZSgiZmlndXJlcyIpLGZpbGVuYW1lID0gIm1vZGVsX2ludGVyY2VwdF9qYWNjYXJkLmpwZyIsIGhlaWdodCA9IDYuNSwgd2lkdGggPSA2LjUsIHVuaXQgPSAiaW4iKQojCiMKIwojYGBgIw==